X ブシリーズ
XI /turbo/Z
試験 c 出
或腰に出
八 ー ドウ エアのフルコース
祝一平著
日本ソフトバンク
まえがき
’85年の6月から Oh ! MZ 誌に連馼を始め,それから2年2か月の間. XI のハ-
ドウ エアを さまざまにいじく リ まくった結果が本省である。 ただし,逄馼時
にあったライン描画,ペイン I 、プログラムなどのグラフ ィ ックに関するもの
などはページ数の関係で除外してある。世の中というものは,そんなものな
のである。
逹馼を始めた当初は,分かっているっもりであったことも,実際に書き始
めてみると意外といい加減な知識しかなかったことに気付き,あわてて調べ
直したことも多々あった。それやこれやで,単純ミスからドタコまで,さま
ざまな間遠いもあったが,そのたびに優秀な読者からご指摘をいただいた。
そう考えてみると,多くのその筋な XI ユーザーの ご助力を抜きにして,本書
はなかったかもしれない。なんて,殊勝なことを言ってみたりする。
ともかく,本書に XI についての私の知識のほとんどを盛り込むことができ
た。読者各位に便利に使っていたた:きたい。そして,ブラックボックスでは
なく,すべてを ユーザーに 解放されたマシンの面白さを知っていただけたら
幸いである。
私的ながら,本書はネムにとって 1 冊目の著述にあたります。1〇〇冊を 一っの
頂点とするなら,ちようどその1/100まで来たことになります。その(私に
とつて) I 己念すべき1冊に XI に巡り会えたことは,幸いなことだったと思い
ます0
1987年晚秋 祝一平
目 次
第 0 章
I/O マッブ
きっと完全無欠な I / O マップ
第 1 章
CRTC
CRTC でビすこいである
籲 HD 46505 -SP なのだ .
♦さらに CRTC を究める .
籲もっと表示するのである .
癱全画面である .
33
38
40
41
31
PCG
PCG は二度おいしいのである
籲 PCG の基本技 . ^
• PCG の定義 . 肪
籲 PCG の高速定義 . 50
籲 CG の読み出し . 56
鲁 turbo における PCG/CG. 57
43
第 3 章
lg | 子 _
渙字名野出唾留
修漢字コードの基本 . 64
籲表示するのである . 68
籲さらに表示するのである . 71
サブ CPU
サブ CPU のおかげなのである
*80C49 なのである . 78
• サブ CPU の実態なのである . 79
春さあて,使い方である . 79
—77
第 5 章
CTC
CTC は律儀なので系名
97
CTC の概略である
CTC なのである
割り込みべクトル
99
99
CTC の使い方である
実技編である
結論である
第 B 章
SIO
SIO でマウスである
113
マウスである
マウスの実技である
114
117
第7章
__信
通信だってするのである
籲それではいぎなり始める .
131
132
第日章
DMA
DMA はへビー級である
籲 DMA の基礎 .
147
□ MA は爆発である…
□ MA は K いのである
149
150
152
第9章 一 i
フロッピーディスク
ディスクを肘すのである
籲フロッピーディスクドライブの種類
籲トラック,セクタなどなど .
175
本題に入る前に
177
180
目 次
•では,始める . 181
癱とりあえず FDC について . 187
• TYPE I の実習 . 190
• TYPEII の実習 . 196
• TYPEHI . 203
• TYPEIV . 217
籲そして DMA である . 217
籲脱線である . 218
•本題である . 218
• 2 H □の物理フォーマットである . 223
籲グラフィックするのである . 225
•ソフト的なフォーマットである . 225
•さらにグラフィックするのである . 225
第10章
PSG
PSG は基本である
籲サンプルなのである"
卿
235
第11章
FM 音源
FM 音源 ナハ トムジーク
• OPM である . 242
籲 OPM の基本 . 245
籲〇 PM のレジスタである . 247
•トーンダイアラである . 257
• MML である . 260
_ MML の機能である . 276
籲おまけである . 280
•解説するのである . 2的
241
第 12 章
第13章
第14章
付 u
力乏 ーゴメ ー ジボ ー ド
カラーイメージボードで 取り込む のである
籲実践するのである . 285
籲気分は近未来である . 289
データ k コーダ_
テープもやってしま5のである
• テープ関係の I / O アドレスである . 300
と1である . 301
籲テープの記録フォーマットである . 302
籲読んだり書いたりするのである . 303
turbo Z
z の機能はおいしいのである
籲グラフィックである . 318
•画像取り込み . 324
A ダンプリストチェック用プログラム . 328
巳 XI 処理技術者試験 . 330
C 初出一覧•参考文献 . 335
I / O マツフ
きっと完全無欠な I / O マップ
この章では Xl/Xl turbo の I/O マップを網羅するのである。この部分は Oh! MZ 誌の
連載時に,初めは「たぶん完全無欠な I / O マップ」として書いたものであるが,あちこ
ちに間違いが見つかり,やがて「ほとんど完全無欠な I / O マップ」となり,さらにバグ
を取って,ここに「きっと完全無欠な I / O マップ」となったのである。相変わらず完全
無欠と言い切らないあたりが微妙にその筋なのである。
マップには ^ uur 加、 之の三つのマークがあるが,それらの意味は,
1) : ノン turbo のユーザーにお勧め(もちろん turbo でも使える)
2) taur 動 KJ •• turbo と Z のユーザーにお勧め
3) Z : turboZ のユーザーにだけお勧め
ということで ある。 参考にしていただきたい。そして注意しておくが, XI の I/O ポー ト
では,たとえば 1802„ 番地は 1800 H 番地と同じで ある。 これは業界用語で言うところのデ
コードされてないというやつで ある。
では, Xl/Xlturbo の 64K バイトにわたる I/O 空間を見ていくのである 0
まず, 図 0-1 は I / O 空間の概観である。
000 0 H 〜 1FFF H までは「ユーザー I/O ポート」と「システム I/O ポート」ということに
なっている。しかし,困ったことにどこまでが「ユーザー」でどこまでが「システム」な
のかは,よく分からないのである。一応ユーザー I/O 領域は 000 0 H 〜 00FF„, システム I/O
領域は 0100„ 〜 1FFF h と考えてよいだろう。
では,番地の小さい方から順にもりもりとやってみるのである。
070 Oh FM 音源/ CTC (
IN/OUT : HZ 7/^
第11章)
( 070 Oh
YM 2151 アドレスボート
OUT
0701 m
L ■■ ■ M 1
YM 2151 データボート
卜 IN/OUT
0704 h |
CTC チヤンネル0
IN/OUT I
0705 m
CTC チヤンネル1 I
IN/OUT 1
0706 h
CTC チヤンネル2
IN/OUT
0707 h
CTC チヤンネル3
_■ ■ ■ ■ 1
IN/OUT
チェックポイント turboZ には FM 音源が入ってい
るが. CTC は付いていない。ただし,0704 h はデー
タラツチ機能があり, FM 音源機能のソフトチェッ
クに使われる。
080 0" カラーイメージボード(—第 12 章)
IN / QUT : i ^ Z 7
0800 m 〔カラーイメージボードコントロール —OUT
080 1 h 「 画像 データ I 充み込み l~IN
チェックポイント Z の画像デジタイズとはまつた
く違う 0
OAOOh 立体ボード/ CTC
IN/OUT : ^7
コント ロール 内容
口-ルデ-夕 D , D 。
スコーブ動作
OAOOh
|立体ボードコントロール
OUT __ ]
0 A 04 m I
CTC チヤンネル〇
IN/OUT
0 A 05 h i
CTC チヤンネル1
IN/OUT
0 A 06 h
CTC チヤンネル2
IN/OUT
0 A 07 h
CTC チヤンネル3
IN/OUT
ルドにおける立体表示するグラフィ
ックスクリ
〇 垂直同期ごと L , R 交互に開閉
1左シャッタ OPEN 右シャッタ CLOSE
〇 左シャック CLOSE 右シャック OPEN
1左シャツタ OPEN 右シャツタ OPEN
垂直同期ごと L . R 交互に表示
LEFT ( PAGEO )
RIGHT ( PAGEl )
〜 D 2 は無効。
,ッタ の OPEN CLOSE は一度設定すると•それ以後はハードがフイールドごとの切り換えを自動的に処理し
れる。 I 季しくは CZ 8 BR 1 の取扱1¢明軎の付錄を参照のこと。
第0章 I / O マップ 11
OBOOh メイン/バンクメモリ切り換え
OUT : t 匿 jrm[
OBOOh
7 6
4 3
0
ンクメモリかを指定する。
0 =バンクメモリ
1=メインメモリ
くンクメモリ〇番ハ*ンクメモリ15番 メインメモリ
00001
7 FFF .,
FFFF ,,
turbo で拡張された部分である。 turboZ II ではバンクメモリ 0,1 番が内蔵されてい
る。以前は, MS(X)-DOS(Multiplan) によってバンク 0,1 番が使われていただけで
あった。 ノーマルな 状態のバンクはシステム内メモリである。
OCOOh RS-232C カード ( CZ-8RS)
IN / OUT :
0 C *0 h J
LZz^_ r/w _
IN/OUT
0 C*lH 1
コントロール,ステータス R/W
IN/OUT
0 C ♦ 2 h
送信 IEO をリセット
OUT
OC * 3 h 1
受 fS IE 0 をリセット
OUT 1
OC * 4 h
送信 割り込み許可
OUT
OC * 5 h
送信 割り込み 禁止
OUT
0 C + 6 h ]
受信 割り込み許可
OUT
OC ♦ 7 h
受信 割り込み 禁止
OUT
チェックポイントアドレス中の•ホ•はデイップスイッチで投定
する。
XI シリーズの旧タイプの RS-232C 力ード (CZ-8RS) である。 turbo のモデル 10 以
外で内蔵しているもの,および RS-232C マウスボード (CZ-8BM2) とは異なる。
12 試験に出る XI
ODOOh 外部闩 AM ボード ( EMM )(-> 第 8 章)
IN/OUT : SZ 7
EMM 0 の場合は次のようになる。
ODOOh
アドレス下位指定 (00 h 〜 FFh )
OUT |
ODOIh
V !
アドレス中位指定 ( OOh 〜 FFh ) ,
_ ■ ■ ---
OUT 1
0 D 02 h 」
アドレス上位指定 (00 h ~04 h )
— 晒 ■ ― 4
OUT
0 D 03 h I
L ■■- 1
データのリード/ライト(内部アドレスは自動加算) ]
IN/OUT
EMM 1 は 0 D 04 … EMM 2 は 0 D 08 h から,というように4番地ごとに計64枚が(スロ
ットの数があれば)つながる。
OEOOh 外部 R 〇 M (巳 ASIC 闩 OM , 漢字 ROM ) (―第3章)
IN/OUT : XKU
0 E 00 m -0 E 03 h BASIC ROM (CZ 8 RB )
OEOOh
卜- ■ ■ ■!
アドレス上位指定 I
OUT コ
OEOIh
アドレス中位指定 1
— ^― ^——- -
OUT
0 E 02 m
アドレス下位指定
OUT |
0 E 03 h
1麵 ■ t
データリード
■細 ■ ■ - - 1
IN
k
0 E 80 m -0 E 82 m 漢字 R 0 M(CZ 8 KR )
—■■ ■ .. ■ —---
0 E 80 h
!■■■' 1
左側データ/アドレス下位指定 (00 h 〜 FFh )
IN/OUT
0 E 81 h
r~ ■ ■ 1
右側データ/アドレス上位指定(〇〇»〜 FFh )
' IN/OUT
0 E 82 h
(0 E 82 h ) — 01漢字 ROM セレクト
(0 E 82 h ) —00 壜設用 EPROM セレクト
1 ■ ■ 1
OUT
0 E 80 h ~0 E 82 h 增設用 EPROM (カナ漢字変換 ROM )
^ 0 E 80 m
[ ■ i
r M ■■ -
ROM 1 データ/アドレス下位指定 (00 h ~ FFh )
P IN/OUT
0 E 81 h
卜 ■ (
ROM 2データ/アドレス上位指定 (00 h — FFh )
し _ . .—
IN/OUT
0 E 82 m
L ■— ■ ■■ J
(0 E 82 m ) —00 增設用 EPROM セレクト
(0 E 82 h ) — 01漢字 ROM セレクト
-— 1
圓
OUT
BASIC ROM には,アドレスの自動カウントアップ機構はないようである。また,ア
ドレスの指定は上位,中位,下位の順で外部 ROM ボードとは異なっていることに注意し
ていただきたい。漢字 ROM のアクセス方法などに関しては第3章を見ていただきたい。
増設用 EPROM は, 8 KX 2個がささるようになっている 。 HuWP (ハドソン)に付属し
ていたカナ漢字変換 ROM (1.0 データ機器製: PIO -3055-01) である。しかしながら,
X1G model 20などはそのような ROM がささる場所はなく,「辞書はディスク上に持
つ」という状況である。すなわち過去の遺物である。
OFDOh 八 ー ドディスク
IN/OUT :
F _ " "" T ■■■■ ■ ■ »■ ■! I
OFDOh
卜 i ■■ ——■
r ■ ■ ■ ■!■ ■ — ■胃
L データ
IN/OUT
OFDIh
0 FD 2 m
0 FD 3 h
l ■_ — 1
コントロール
1 1
第0章 I / O マップ 13
相変わらずアドレスしか分からない。ハードディスクは SCSI 準拠であるから,将来的
には CD - ROM なども付くはずなのだが,ど一なるのであろう。また, XI にもつながる
はずなのであるが,’87年11月現在もサポートがない。む一ん。
0FE8h 8 インチ FD
IN/OUT : t 鼠 jribB
0 FE 8 m
ステータスレジスタ/コマンドレジスタ
IN/OUT
0 FE 9 h
I トラックレジスタ
IN/OUT
OFEAm ,
セクタレジスタ
IN/OUT
OFEBm
データレジスタ
IN/OUT
OFECh |
FM 方式指定ドライブ No ., サイド,モーター 0 N
IN OUT (
OFEDii 1
MFM 方式指定
1
IN
OFEEii
1.6 M タイブ指定
■ ■ ■ m i
IN
OFEFm
500 K .1 M 切り換え I
IN
OFECh 出力内容の意味
7 6 5 4 3 2 1 0
ドライブ No .(0 〜 3)
サィト•叫?:
モ-夕- 0 曝: ?: on F
turbo / Z では8インチ FD を4台まで接続できるのである ( 5インチ FD とは別)。し
かし’87年11月現在もまったくサボートされていない。5インチ FD の 2 HD が主流であ
るから,それも致し方ないであろう。8インチ FD のコントロール内容は, I / O アドレス
がずれている以外は5インチ 2 HD と同じである。ただし, 0 FEF „ 番地は無意味である。
0FF8h 5 インチ FD (— 第 9 章)
IN/OUT : XKI7 / ^M/rM7£7
0 FF 8 ll
ステータスレジスタコマンドレジスタ
IN OUT
0 FF 9 .I
トラックレジスタ
IN OUT
OFFA11
セクタレジスタ
1 IN OUT
OFFBn 1
データレジスタ
IN OUT
OFFC.I
FM 方式指定ドライブ No .. サイド.モーター 0 N
IN OUT
1 _ •— — — • •禮
OFFDn
MFM 方式指定
IN
OFFE.i
1.6 M タイプ (2 HD ) 指定
IN
OFFF11 ,
~ 500 K (2 D ) ; 1 M (2 DD ) 切り換え 1
IN
OFFCh •出力内容の意味
7 6 5 4 3 2 1 0
.xxrmm
ドライブ No .(0 〜 3)
サイド指定
0 =サイド0
1=サイド1
モーター 0 N /0 FF
0 =0 FF
1 =0 N
14 試験に出る XI
1000 H , 1100 H , 120 Oh グラフィックパレツト(一第14章)
IN/OUT : ^7/^
XI パ urbo および Z でのコンパチモード ( OUT のみ )
この三つの I / O ポートは一組になっている A
10* *H
11* *H
12+ *H
縦1列の3ビットを3桁の2進数 ( 〇〜7 ) と
みなし カラーコー ドにする。
えば,第4ビットの縦1列が
(右に90度回転すれば & B 1 10 = 6)
は 「PALET 4, 6 j に対応する。
チェックポイント標準状態 (「 INITj の後)は以下のとおりである。
(10** m ) — AAm = &B 10101010
(11** h ) 一 CCh = &B 110 0110 0
(12 本*") — F 0 h =&B 11110 0 0 0
「*」 印は何でもよいということである。またもや業界用語で言うところの「デコード
されていない」である。このポートは出力のみである。うっかり IN すると,パレットの
状態が変化してしまう。注意していただきたい。
turboZ の多色モードの場合 ( IN/OUT 可能 )
この12ビットでパレット この12ビット (4
コードを指定 ビット X 3 回)で
カラーコードを
2) 64色モード 指定
上記の G . R . B において,各4ビット中の右側2ビットを 00 b として指定
する ( G , R , B はそのまま4ビットすつ)。
チェックポイント Z でパレット R / W には, 1 FC 5 h も参照のこと。
第0章 I / O マップ 15
130 Oh ブライオリティ
OUT : XKU
7 6 5 4 3 210
それぞれのカラーコードがテキストより優先するかを決定する。
たとえば第5ビットが1ならば.カラーコード5(=シアン)はテ
キストよりも優先する。第0ビットは,背景を意味する。
BASIC の PRW に指定する数値と同じである。
チェックポイント Z の場合は IFCOh も参照。
1400h,150(K1600h,1700h, CG, 漢字 ROM,PCG アクセス (— 第 2,3 章 )
IN/OUT : I taur 勳 n
Xl/Xl turbo コンパチアクセスモード
14本* H
CG ROM アクセス
,
IN
15本本 H
PCG BLUE アクセス
IN/OUT
16* * H
PCG RED アクセス
IN/OUT
-- — -|
1 フ ホ +H
PCG GREEN アクセス
1. ■ I. ■ I. ■ ■■ ■ ■ ■ - J
IN/OUT
XI turbo 高速アクセスモード
r . - . - m
r - - 1 - —■■ i
14*0 h 〜 14* F»i
L — 1
CG , 漢字 ROM アクセス
IN
i 1
r ■ X
15*0 h -15* Fm
PCG BLUE アクセス
IN/OUT
16 * Oh 〜 16 * Fh
-
PCG RED アクセス
IN/OUT ;
17 * 0 h -17 * Fm I
PCG GREEN アクセス
L - - ■ ■ ■ ■■■__ ■■<
IN/OUT
1 — _■ J
チェックポイント turbo の場合, I / O ポート IFDOh の第5ビット
が1ならば高速アクセスモード,〇ならばコンパチアクセスモード。
180 Oh CRTC (— 第 1 章 )
OUT : XKI7
y ■ ■ ■■ ■ ,
180 Oh
CRTC レジスタ No •指定 (0 — 17) |
1801 h
CRTC レジスタへのデータ (00 h — FFh ) ;
[ ■■■— ■ ■ ■ ■」
(CRTC の型番は HD 46505 - SP )
チェックポイント40/80桁の切り換えには, I / O ボート 1 A 02 h の
第6ビットが間係している。0なら80桁,1なら40桁。
turbo では400ラインになったことに加えて,アンダーラインモ
ードも加わったので, 1 FD 0 h もいっしょに設定しなければならな
い場合がある a
18個ある CRTC のレジスタのうち実際に意味があるのは12個である〇 XI ではスーパ
ーインポーズ時にスクロールできるが,これは CRTC の5番レジスタ ( R 5) を書き換
え,さらにポート 1 A 02„ の第4ビットを0にすることで行なえる。いろいろいじくりま
わすと面白い石である。
76試験に出る XI
190 Oh サブ CPU 80 C 49(8255 ① )(4 第 4 章)
IN/OUT :
グルーフ|_ボート 端子 コ Vhn _
ボート端子
PA; I
PAs
PAs "]
■ j
PAi
PA3 ;
一 1 4
pa 2
- j
PAi
PAo
- 1
PC;
PCb I
I
PCs
ロール 内容
アクティブ
Z 80 とのデータ入出力 ( IN / OUT )
(1900 m )
Z 80 A に対してデータ受け取り指示信号
Z 80 A がボート A からデータ受け取り信号
Z 80 A に対してデータ転送禁止信号
カセツト LED の点灯 ( H : READ . L : WRITE )
PC (
PB
PB ,
PB
PB
PB :
PB ,
PB ,
PBo
_ Z 80 A への BREAK 信号
, カセツトの EJECT ソレ
• OBF 信号
ACK 信号
APSS (_ 記錄部梭出)
EJECT SW センス
ドコ
PB と カセットテープの香き込み禁止用の爪がある状態 : h |
PB , 1カセットがセットされている状態 1 h
PBo ;テープエンド検出 l
チェックポイントこの図は 80 C 49 から見た場合である。このとき Z 80 は 80 C 49 の周辺デバイスとみ
なされる。 Z 80 から入出力が可能なのはポート A ( PAo 〜 PA ?) だけである。
チェックポイントを繰り返すが,ポート B ( PB 0 〜 PB 7 ), ポート C ( PC 。 〜 PC 7 ) を
Z 80 が直接変化させることは できない。 サブ CPU 80 C 49 と交信して間接的にアクセスし
なければならない。 結局,実際に意味があるのは190 0 H 番地だけと い うことであり, Z 80
はこのポートを使つてサブ CPU と会話することになる。当然8255のモード設定などは
Z 80 側からは 行なえない。 サブ CPU のアクセスには8255②を参照のこと。
第0章 I / O マップ 17
ード 0
(グル—ブ
モ丨ド〇
18 試験に出る XI
8255 ビツト•セットリセット(ビット7 = 〇)(ポート C に対して)
1 A 03 m
7 6 5 4 3 2 1 0
1 I 11
無効ビット
%% J 卜•十^ %% j k 11 Jr? %v k
0
リセット
し / 1 しノ r J \L / V
丁
セット
ナエックポイントビット•セットリセット制御はボート C (1 A 02 H ) の任意の1ビッ
卜を変化させるもので,ブログラムを高速かつコンパクトにできる
8255②は①と違って別に変わった使われ方はしていない。ここは重要なので少々丁寧
に説明する。
ブリンタへの出力は,
1) BUSY ( PB 3 )= 0まで待つ
2) ポート A (1 A 00„) へデータを出力
3) PC 7 を立ち上げる(?4〇— 1)
で行なえる。
PB 7 (垂直帰線期間信号), PB 2 (垂直同期信号)は CRT の状態読み出し。特に PB 7 は
PCG アクセス時に重要である。
PB 6 (データ転送禁止信号)はサブ CPU との会話用に使われていて, PB 6 =1 はサブ
CPU からの「待ってくれ」を意味する。
PB 4 は現在のバンクが BIOS (IPL) ROM 側か,メインメモリ側かを検出するものであ
る。 turbo のみの機能である。
PB 1 はカ セッ トからの読み出しデータ。
PB 0 はサブ CPU からの信号で, CMT が PLAY 中に| BREAK |キーが押されたときな
どに0になる。
PC 6 は80, 40桁の切り換え。
PCs は立ち下げ (?—1—0) で同時アクセスモードになる。ただし,その前に DI で
割り込みを禁止しておくこと。このモードを解除するには,何でもいいから IN 命令を実
行すればよい。詳しくはへ。
PC * は0のとき CRTC の5番レジスタとともにスムーススクロールを実現する(スー
パーインポーズ 時)。
PC 0 はカセットテープへの書き込みであるが,任意の長さの「1」を書けるわけではな
い0
なお,モード設定は IPL が行なってくれるので別にユーザーは気にする必要はない。
第〇章 I / O マップ 19
ボート C ビット選択
ビット
0
1
2
3
4 5
6
7
' D , ,
0
1
0
1
0
0
〇 1
d 2 1
0
0
1
1
0
十
1
d 3
0 ,
0
0
0
■ \
1
— ■ 麵 —J
1
- 1
1
1B**h,1C**h PSG, ジョイスティック( — 第 10 章 )
IN/OUT : HZ7
• ■ ■ ■
1B* *»
PSG データ ( 00h 〜 FR ,) I
IN/OUT ]
1C* *H
L -<
PSG レジスタ 指定 (〇 〜 15)
OUT
ジョイスティックのデータの 意味 ( Ri 4, Ris )
7 6 5 4 3 2 1 0
0=向こうに倒した
0=手前に倒した
0 =左に倒した
0=右に倒した
未使用
〇 =トリガー1を押した
〇 =トリガー2を押した
未使用
PSG ( AY -3-8910) へのアクセスである。ジョイスティックをアクセスするには PSG
のレジスタ, R 7 , R m , R 1 S を使う。次のブログラムは, JOY 1, JOY 2 をともに読み出
し,データを表示するものである。
10 OUT & H 1 C 00, 7 : ’select register
20 r 5 = INP (& HlB 00) AND & B 111111
30 OUT & H 1 COO , r 5 : ’set register
40 1
50 OUT & H 1 C 00,14 : jl = INP (& HlB 00)
60 OUT & H 1 C 00,15: j 2 = INP (& HlB 00)
70 PRINT BINS ( jl ), BIN $ ( j 2)
80 GOTO 50
ジョイスティックからの入力は負論理である。なお,レジスタ番号の指定は1度行なえ
ば続けてアクセスする際には再指定する必要はない。
ID* *hJE* *H IPL(BIOS)ROM on/off
OUT : XKU/^M/r£7£7
1 D + 丰 H
r —■ ■ ■■国
IPL ROM ON
OUT
I
1E**h j
IPL ROM OFF
OUT
チェックポイント OUT するデータはなんでもよい。
ROM を ON にすると0000 h ~ 7 FFFh までが ROM に切り換わる。
したがって,それを直接行なう OUT 命令は800 Oh 〜の位置になけ
ればならない。
ROM が ON のとき〇番地へジャンプすれば IPL が起動する 。 R
0 M が ON のときに, 000 Oh 〜 7 FFFh にデータの害き込みを行なう
と. RAM に害き込まれる。しかし I 光み出しは ROM から。この手
法は シャ ドウ RAM と呼ばれる。これにより 64 K バイトを一発で口
ードできる。
1 A 01 H 番地の PB 4 も参照。
20 試験に出る XI
LD
BC ,1 D 00 H
OUT
( C ), A
X 0 R
A
LD
(100 H ), A
LD
A ,(100 H )
LD
BC ,1 E 00 H
OUT
( C ), A
とすると, A レジスタに何が入っているか? 〇ではない。
1F8*h DMA (— 第 8 章)
IN/OUT : taurEJU
1 F 8*„ DMA へのコマンド,データ ] IN/OUT
Z 80 DMA コントローラは(メモリ, I / O ) —(メモリ, I / O ) 間のデータ転送を高速に行
なうための LSI である。 DMA にはデータ転送ばかりではなくサーチ機能もある。また
転送でも特定の番地の内容を,ある範囲にコピーすることができる。すなわち G-RAM
全域に0を転送することも可能である。この手法を使えば高速画面クリア,スクロールを
実現できるが , turbo BASIC では使用していないようである。
1F90h SI 〇第 6,7 章)
IN/OUT :
r ■ -•
XKLJ I^MJrEJEJ
1 F 90 h
卜- — ■
チヤンネル A データ
IN/OUT |
1 F 91 h
!■ .
チヤンネル A 制御
IN/OUT
1 F 92 h ,
チヤンネル B データ
IN/OUT
1 F 93 h
^ ■ ■ ■圓 ■ 1
チヤンネル B 制御
_ ■ ■ ■ _ ■ ■ 1 ■ 1
IN/OUT
チェックポイントチヤンネル B はマウスにつながっている。ボー
レートは4800 bps である。
RS -232 C 力ード, CZ -8 RS とは互換性がないことに注意が必要。
CZ -8 BM 2 上の SI 0 のアドレスは 1 F 98„〜1 F 9 B „ が割り当てられている。この力ードに
は CTC が入つていて,こちらの方のアドレスは 1 FA 8„〜1 FAB „ となる。これは CTC が
ボーレートジェネレータの役割をしているためである。
IFAOh CTC (— 第 5 章)
IN/OUT \ HDrM:MjrMitJ
IFAOh
!■ ■ I
ヤンネル 0
タイマモード
IN/OUT
IFAIh
チヤンネル l
SI 0 チヤンネル A クロック
IN/OUT
1 FA 2 h
チヤンネル2
SI 0 チヤンネル B (マウス)クロック
IN/OUT 1
1 FA 3 h
L 1
チヤンネル3
カウンタモード
IN/OUT
チェックポイントチヤンネル〇の使うクロックは 4 MHz , タイマ
周期は 4“ sec 〜 16.384 msec まで。チヤンネル1, 2は 2 MHz のクロ
ツクを使用。チヤンネル3はチヤンネル0をカウントし,最長夕
イマは4.194 sec 。
第0章 I / O マップ 21
SIO の所で説明したように, 1 F 98 H 〜1 F 9 B H にもう一つの CTC を付けることができ
る。また, FM 音源ボード,立体ボードなどにも CTC が載る0
IFBOh Z モード指定( — 第 14 章 )
IN/OUT : Z
データ 内容
ロール
:•ット〇
〇 =インタレーススーパーインポーズしな L
1=インタレーススーパーインポーズする
|ビッ
無効
ビット2
:•ット3
ビット4
0二画像取り込みの階 M ノーマル
1=画像取り込みの階 M 反転
0=画像取り込みをしな L
1=画像取り込みをする
0 =4096色1画面モード指定
(ビ
•ン
7. 3 =1のときのみ有効)
= 64色2画面モード指定
X ) (ビット7 =1のときのみ有効)
)(320 x 200 のときのみ有効)
5 無効
ット6 無効
0 = X 1/ X 1 turbo コンパチモード
1=多色 ( turboZ ) モード
1FB9m~1FBFh Z テキストバレット指定( ― 第 14 章 )
IN/OUT : X
アドレス 1
コントロール
1FB9»i I
青のカラーコード
lFBAu
赤の カラーコード
lFBB .. 1
マゼンタのカラーコード 1
lFBCn
綠の カラーコード
IFBDii 1
■ — — - ■ —■ — — ■ ■■ —■ _ ■ ■ ■ - ----- - ----4
シアンのカラーコード 1
IFBEii
黄のカラーコード
lFBF.i
麵 ■■ ■■i■ ■ ——■■ ■ — 4
白の カラーコード
段定 データ
7 6 5 4 3 210
贩丁 TTrn
mm
1 - B
- R
1 - G
RGB 各 2 ビットずつ =64 色を指定できる。
IFCOh Z ブライオ 1 J ティ指定( — 第 14 章 )
IN/OUT : Z
データ 内容
コント ロール
0, 0 =テキストはグラフィックより優先
1 • 丨 礞
0. 1=グラフィックはテキストより優先
ヒット 0,1
1, 0 =テキストはグラフィック2面の間に入る
1. 1=未定義
22 拭験に出る XI
ビット 3, 4は2画面モード(― IFBOh 番地のビット 4) のときのみ有効。
• 多色 ( turboZ ) かつ 320 x 200 モードでのみ意味のあるポート
• ビット4 = 0のときはビット1= 0とみなされる
•ビット4=1のときは IFDOh のビット3は無効
IFCIh Z 画像取り込み位置補正指定(—第14章)
IN/OUT : Z
7 6 5 4 3 210
〇〜255の桶正ドット数を指定する。
• 200ラインモード ( IFDOh のビット 0 = 0) のときのみ有効
1 FC 2 H Z モザイク/置子化取り込み指定 (4 第〗4章)
IN/OUT
6 5 4 3 2
X 方向モザイク
子化指定
シント71ビット6 階調
0 〇 4ビット階調取り込み (4096 色)
0 1 3ビット階調取り込み (512 色)
1 0 2ビット階調取り込み (64 色 ) i
1 1 1 |1ビ ット階調取り込み (8 色 ) J
、 64色モードを指定してある場合はビット7=1とし-
1FC3h Z クロマキ ー 指定( ― 第 14 章 )
IN/OUT : Z
7 6 5 4 3 210
5
1 1
4 3
2
1
0
クロマキーの色指定
(8 色)
W
0
- 0
_ 1
t 1
0
果
0
一 0
一
1
一
宵
0
- 1
—
0
一
赤
0
礞
- 1
—
1
マゼンタ
1
- 〇
一
〇
-
綠
1
一 0
1 —
1
シアン
1
- 1
—
0
-
黄
1
^ - - ヤ普
, L
1
白 !
0 :反転クロマキー OFF
、 1 :反転クロマキー ON
0 :クロマキー指定 OFF
: 1 :クロマキー指定 ON
ヒット 0. 2. 4 は抹けている。
ビット 7 = 0 のときビット 6 は無効。
クロマキーとは.映像画面中の指定した色を抜いて.そこにコンピュータ画
面をはめ込むものである。
1FC4h Z スクロール指定(—第 14 章)
IN/OUT : Z
データ内容 ]
コントロール
ビット 0
1-
〇 =スクロールインする
1 =スクロールアウトする
ビット 1
〇 =スクロールイン.アウトを繰り返す(旧モード)
1= 一度出たら,スクロールインしない
ビット 2
0=CRT 出力する
1 =CRT 出力しない
ビット 3
0 =ビット〇〜 2 を無効とする
1= ビット〇〜 2 を有効とする
ビット 4
\
未使用
ビット 7
■ ■ —■ — _ ■ ■ J
チェックポイントビット 3 = 0 のときビット〇〜 2 は無効。これは,ス
ーパーインポーズと組み合わせて,「一度だけスクロール」を実現するもの
である。 CRTC と 8255 ②も必要。
1FC5h Z 多色モードでのグラフィックパレット制御指定( — 第 14 章 )
IN/OUT :,
7 6 5 4 3 210
0=パレット害き込みモード
1=パレット轿み出しモード
0 =アクセス OFF (ビット 3 無効)
1 ニアクセス 0N (ビット 3 有効)
チェックポイントこのボートは多色モードでのみ有効。 10** h 〜12 **h
と組み合わせて使う。
24 試験に出る XI
IFDOh 画面管理( •- 第 1 章 )
(IN)/OUT : t 匿 jr^Jd
:データ内容
コントロール 1
ビット0
0=低 解像度 モニタ (200 ライン)
1= 高解像度 モニタ (400 ライン)てータ切ノ換又
L - _
ビット1
0=1本ラスタ/ドット
; 1= 2本ラスタ/ドット
_
ビット2
〇 = ノーマル (8 ラスタ/ CHAR )(25 行. 20行)
1= 漢字 (16 ラスタ/ CHAR )(12 行, 1〇 行)
ビット3
■ ■ ■ <
0ニバンク0 表示
1=バンク1 表示 |
ビット4
0 =バンク0アクセス
1=バンク1アクセス
ビット5 ,
—
0 = PCG コ ンパチアクセス |
1 =PCG 高速 アクセス
ビット6
0 = 8ラスタ CG アクセス
1=16ラスタ CG アクセス
ビット7
L- -1
〇= アンダーラインなし
1=アンダーラインあり
チェックポイント BASIC 起動直後はビット1=1である。これによりグラフィ
ックを高解像度モニタで200ラインとして扱える(文字の方は400ライン)。 turbo
では,グラフィックが400ラインモードのときは偶数段目がバンク〇,奇数段目が
バンク1の内容が表示されている。ビット1が1であるということは.そのとき
表不されているバンク(ビット3で指定)の内容のパターンを下の段にも繰り返し
表示させるものである。
おそらくこの脱明では理解できないだろう から, 次のプログラムをサンプルと
して示す。
1〇 OPTION SCREEN 0 : WIDTH 80.25,0.2
20 GRAPH 0,0,0 : CLS 4 : SYMBOLdOO , 30) , •バンク 0,, 5,5,1 , 0, PSET
30 CHAPH 2.2,0 : CLS 4 : SYMBOL(100,70), • バンクド, 5,5,2,0, PSET
40 OUT &H1FD0.&B1 100001: AS = INKEYS (1)
50 OUT &H1FD0.&B1100011 : A$ = INKEYS (1)
60 OUT &H1FD0.&B1101001 : AS = INKEYS (1)
70 OUT &H1FD0,&B1101011 : A$ = INKEYS (1)
また, turbo では OUT だけだが, Z では IN も可能、
ここは結構複雑である0ビット1はサンブルブログラムで理解して欲しい。ビット2は
テキストの25 (or 20) -12 ( or 10) 行の指定に使う。 CRTC の設定と一緒に操作しな
ければ表示が乱れる。ビット3, 4は 簡単 だと思われるが念のために言うと, 640 X 400
のモードのときビット3はどうでもよい。ビット1が0なら400ラインを表示する。ビッ
卜5は PCG のアクセス方式を変えるということで, PCG にアクセスする際には設定が
必要である。
ビット6は8 x 8と8 x 16 の 2 種類ある CG のどちらを読み込むかの指定である。画
面表示には関係しない 0 ビット7はアンダーラインの指定。ここが1であり,アトリビュ
一 卜(漢字 VRAM のビット 5) が1なら, ( CRTC の設定も許すなら)アンダーライン
が表不される。ちなみにアンダーラインの色はグラフィック1(青)の色に設定され てい
るものが表示される 0 BASIC のマニュアルにもあるように,
第0章 I / O マップ25
KSEN 1, 色
PALET 1 ,色
は同じ意味を持つ0これはアンダーラインモードを使った後はパレツトを再設定すべきで
あることを示す0また気分が乗れば, PALET 命令の代わりに KSEN 命令を使うのもお
つであろう。
(1 = 0 N , 0= OFF )
チェック ポイント グラフィックを 黒変換す るためには,パレットが0になつてい
なければならない c また. turbo では OUT だけだが. z では IN も 可能。
黒変換とは早い話がスーパーインポーズ時の黒抜きである。必要のない人には必要ない
のだが,欲しい人には盆と正月がいっしょに来たようなものであろう。
IFFOh スタートポート
IN : tmjr 動 D 11
turbo および, Z の背面ディップスイッチ SW5 が OFF = 上側のとき
7 6 5 4 3 2 1 0
本体前面の HIGH (= 0)/ STANDARD (=1) スイツチ
SW 1) 本体背面ディップ
SW 2| スイツチ(0~7)
SW 3 J (0 N = 下側で〇)
SW 4
FD DATA
Z で SW 5 が 0 N = 下側のとき(工場出荷時)
7 6 5 4 3 2 1 0
本体前面の HIGH (= 0) STANDARD (=1) スイッチ
0
本体前面の 2 D (= 0) ノ 2 HD ( = 1) スイッチ (START DISK )
SW 4
FD DATA
チェツクポイントビット1、 3 UB 00 T 時のディスクを指定する。 SW 4 は意味を持たない。
1FE0H 黒色制御
(IN)/OUT :1
データ内容
ビット0
frM7£7
コン
黑変換するテキストの色を指定(〇〜 7)
卜5
^6
テキストの黒変換の 0 N /0 FF
グラフィックの黒(透明)を黑変換
グラフィックの靑を黑変換
ブラン キング期間(枠)を 黒変換
未使用
26 試験に出る XI
| No •コ
SW 3
r - - ]
SW 2 SW 1
セレクト
容置 ^
記録方式
フォーマット
0
0
0
ド ■ ■ ■ - ■ |酬
0
5(3) インチ
320 K バイト
2 D :両面倍密度
1:
0
--
0
1
1
5(3) インチ
640 K バイト
1-
2 DD :
0
> ■ j
w
1
0
5 インチ
1 M バイト,
2 HD :両面高密度
3
1 ■ ■ ii 1
0
' V
1
1
5インチ
产 — ■ ■ _ 画
1 M バイト
2 HD :両面高密度
IBM
4
r 1
r -■ i
1
0
0
8インチ
1 M バイト
2 D256: 両面倍密度
5
L ■ ■- ■ J
1
1 _ _ J
0
r - - 一 參
8インチ
1 M バイト
2 D256: 両面倍密度
IBM
6
1
1 i
8インチ
240 K バイト
1 S128: 片面単密度
IBM
7
1
■■ ■
1,
» .1
1
ハードディスク
10M バイト
1_
し- — -
これらのスイツチはただ単に付いているだけである。 IPL などのプログラムがここを
見て,その設定にしたがった動作をするわけである。早い話が「フラグ」である。
背面ディッブスイッチの SW 4 は無意味なので,ときには OFF 側に倒して気分を変え
るのもよいだろう。
表中の2と3, 4と5は同じではない。 IBM フォーマットではサイド0,トラック0
が FM (単密)記録方式になっている。なお,ビット7の 「FD DATA 」 がその筋であ
る。
ところで初期のころの turbo (市販版かどうかは定かではない)の中には, SW 1
〜 SW 4 の順が逆になっているものもあるらしい。
ちなみに Z の背面ディッブスイッチ SW 6 もディスクに関係している0詳しくは Z のュ
ーザーズマニュアルを参照。
200011 -27FF .. テキストアトリビュート
IN/OUT :
アトリビュート内のビットの意味
7 6 5 4 3 210
-热滅 (=1)
、 - CG (= 0)/ PCG (= 1 )
- — -垂 S 方向2倍モード (= 1 )
1 -水平方向2倍モード (= 1 )
チェックポイント当たり前のことだが,アトリビュートの内容が
0なら色が黒,だから,なにも見えない。 Z では 1 FB 9 h も参照。
3000m-37FFh テキスト VRAM
IN/OUT : I tmjrbn
7 6 5 4 3 210
1 -キャラクタコード (00 H — FF h )
チェックポイント turbo で漢字を表示する場合は,漢字 ROM ア
ドレスの下位8ビット。
第0章 I / O マップ27
380 Oh 〜 3FFFh 漢字 VRAM (- 第 3 章 )
IN/OUT : tEjr 加
7 6 5 4 3 210
——漢字 ROM アドレス上位4ビット
——第1水準(=0)/第2水準
orPCG 外字モード (=1)
——アンダーライン (=1)
——漢字左半分(=0)/
右半分 (=1)
—— CG , PCG (= 0)/
漢字 (=1)
チェックポイント下の表を見よ 0
テキストアトリビュート
ビット 5 = RC1^RAM
漢字 VRAM
表示
ビット 7 = 漢字
ビット 4=1/2 水準
0
0
無閗係
CG
1 〇
1
〇
漢字(第 1 水準)
0
1
1
漢字(第 2 水準)
. - 一 - — ’
1
〇
0
PCG (ノーマル)
1
1 1
0
PCG 外字①
1
1
無閫係
PCG 外字②
PCG 外字モードというのは,2個の PCG を使って 8 X 16のキャラクタを構成するも
のである。4個の PCG で外字一つであるから turbo では計64個の外字 (8 色入り)を
使えることになる。外字の出し方には2とおりあることが表からも分かるが,これは
BASIC 上で,全角 (16 X 16) と半角 (8 X 16) の二つを区別するために作られたものだ
そうである。
400 Oh 〜 FFFFh グラフィック RAM
IN/OUT : XKU/ tMjrlD
ノーマルモード 同時アクセスモード
C 000 •
G
FFFF
B . R.G
R-G
B.G
B.R
チェックポイント同時アクセスモードは 1 A 02 h ,
turbo でのバンク切り換えは1 FD 0 Ha
28 试験に出る XI
XI のグラフイックマップは少々複雑であるが,次の式で BLUE 上のアドレス(4000„
〜 7 FFFJ が計算できる。
X = X 座標 , Y = Y 座標として 640 X 200 のとき,
&H 4000 +( X ¥8) + ((Y AND 7)* 2八 11) + ( Y ¥8) * 80
320 X 200 の場合は最後の 、、*80" を 、、*40" に変えればよい。ここ以外はシフトで計
算できるからマシン語で組むのは簡単である。
XI turbo の400ラインではバンク〇とバンク1が1段おきになっていて,銳く上位コ
ンパチを保っている0 400ラインの場合のアドレス計算は , Y AND 1をバンク No •と
し , Y = Y ¥2 として,前述の値を計算すればよい。
また, Z では4096色モード,64色モードが加わっているが,その色は,ページ〇,
1,2, 3の順に薄い色になっている(ページとは, SCREEN , GRAPH 命令で指定す
るやつである)。詳しくは第14章を参照。
第〇章 I / O マップ 29
CRTC
CRTC でどすこいである
■第 1 章
nCRTCI とす二い I おる
この章では CRTC をまな板に上げるのである。 CRTC というのは , CRT Con ¬
troller , すなわち CRT = 画面表示をコントロールする LSI のことなのである。つまりはキ
ャラクタやらグラフィックやらを, CRT に送って表示する役割をしているのである。
まずは, CRTC がどのようなものかということを目で見るために,リスト 1-1 を実行し
ていただきたい。突如現れる十文字である。しかも微妙なぼかしに,そこはかとない風情
を感じるのは私だけではないだろう。このブログラムのネタは単純である 0 SCREEN コマ
ンドを使って画面に表示するページを,ページ0とページ1の間で高速に切り換えている
ために,二つの画面が重なって見えてしまうのである。ほら,何枚かの紙に少しずつ違う
絵を描いて,パラパラとやると動いているように見えるというアニメーションの基本があ
るが,あれを二つの画面(ページ)でやっているのである。
リスト 1-1 ぼかし十文字
100
WIDTH
40:INIT
110
GRAPH
0,0:CLS 4
120
PRINT
STRING* <40,
130
GRAPH
l f 1:CLS 4
140
PRINT
STRING$(40 f M | M )
150
GRAPH
0,0:GRAPH 1,1 : GOTO150
で, 「 BASIC でこのようなことができるのであれば,機械語を使えばもっと美しいこと
になるのではないか」と思う人が少なからずいるであろう。しかし, 世の中はそう甘く
ないということをリスト 1-2 で嚙みしめていただきたい0
リスト 1-2 ぼかし十文字機械 K 版
100 WIDTH 40: INIT
110 GRAPH 0 f 0:CLS 4
120 PRINT STRING$ 《 40,
130 GRAPH 1,1 : CLS 4
140 PRINT STRINGS(40 # M | M )
150 f
160 CLEAR &HFE00 : A=&HFE00
170
READ
DS:IF D$=
"END.
1 THEN
190
180
POKE
A,VAL( M &H
”+D$>:A=A+1:GOTO170
190
CALL
&HFE00
200
9
210
DATA
01,01 , 1A
t
LD
BC f 1A01H;8255
220
DATA
D9
t
EXX
230
DATA
01,00,18
9
LD
LD
BC f 1800H
240
DATA
3E f 0C
t
A,0CH
250
DATA
ED, 79
#
OUT
(C) f A ;SET AR
260
DATA
0C
9
INC
C ; BC=1801H
266
f •
9
270
DATA
CD,1B,FE
1 LOOP :
CALL
EDGE
280
DATA
AF
>
XOR
A
32 試験に出る XI
285 DATA ED, 79
’ OUT (C) f A
290 DATA CD,IB,FE
f CALL EDGE
300 DATA 3E,04
1 し D A,04H
305 DATA ED,79
’ OUT (C),A
310 DATA 18, FI
1 JR LOOP
320 , FE1B
t
330 DATA 1)9
•EDGE : EXX
340 DATA ED,78
, EDGE1: IN A,(C)
350 DATA F2 f 1C,FE
f JP P.EDGEl
360 DATA ED,78
, EDGE2: IN A f (C)
370 DATA FA , 21,FE
1 JP M f EDGE2
380 DATA D9
1 EXX
390 DATA C9
' RET
400 DATA END
リスト 1-2 の機械語ルーチンでは,垂直帰線期間のエッジ(立ち下がり)を検出し,ぺ
ージの切り換えを行なっているのである(第0章の8255②のポート B を参照)。もちろん
そんなものを検出せず,機械語まかせに「たたたたた」とページ切り換えをしてもいいわ
けであるが,そうするともっと美しくないことになる(ブログラムを変更できる人はやっ
てみることをお勧めする) 0 それはともかくリスト 1-2 では機械語ルーチンの中に入った後
は無限ループになっているので,止めるときはリセットスイッチ ( NMI の方)を押してい
ただきたい。それで結果であるが, BASIC でやったのと似たようなものである。すなわち
この「忍法二重画面」はあくまで「こんなこともできる」というだけなのである。
具体的な解説を行なう。表示画面の切り換えは, CRTC のレジスタの軎き換えで行なう
のである0すなわち表示開始アドレス ( CRTC にとっての VRAM 上のアドレス)を変え
てやるのである。しかし,いきなりそんなことを言われても理解不能であろう。それが普
通なのである。よって,まずは CRTC の基本からやってみたいと思うのである。
HD4B505-SP な访だ
表 1-1 を見ていただきたい0これは XI に使われている CRTC , HD 46505 - SP のレジス
夕機能表である(—参考文献3)。この CRTC は18個 ( R 0 〜 R 17) までのレジスタを持
ち,これらのレジスタに値を設定してやる(書き込んでやる)ことでいろいろな画面表示
を実現するのである。表の右端には,普通の40/80文字モードにおける標準的な設定値を
示しておいたので,図 1-1 と併せて見ていただきたい。ただし,これは低解像度(200ライ
ン)の場合だから, XI でならよいのだが , turbo BASIC ( CZ -8 FB 02) で高解像度モード
(400 ライン)を使つている場合ではちよつと都合が悪いので,その場合はすみやかに CZ -
8 FB 01 (もしくは CZ -8 CB 01) に立ち上げ直していただきたい。
それでは,できるだけ詳しく CRTC の内部レジスタの解説を行なうのである。なお,力
ッコの中の数字は「設定できる値の範囲」を示している。
AR ( 0 〜 17)
まずは隠れレジスタとして AR (アドレスレジスタ)がある。これは,内部レジスタ ( R 0
〜 R 17) のうち,どれにアクセスするかを指定するためのものである(第1〇章の PSG への
アクセスと似ている)。一度設定すれば再設定しない限り AR は同じ値を保持している。
第1章 CRTC 33
表卜 1 CRTC ( HD 46505 - SP ) 内部レジスタ 機能表
レジスタ番号
内 容
機 能
40桁
80桁
R 0
水平総文字数 (一 1)
水平走査の周期を文字数に換算して指定する。
55
111
R 1
水平表示文字数
1行に表示する文字数を指定する。
40
80
R 2
水平同期位置 (一 1)
水平同期信号を出力する位置(文字数)を指定する。
45
89
下位4ビットは水平同期信号のパルス幅を指定0
R 3
同期パルス幅
(文字数に換算)
上位4ビットは垂直同期信号のパルス幅を指定。
(水平走査線本数=ラスタ本数に換算)
52
(34„)
56
(38 h )
R 4
垂直総文字数 (一 1)
垂直走査の周期を文字数に換算して指定する。
31
31
R 5
総ラスタ調整
垂直走査の周期を微調整する。ラスタ数を指定する。
2
2
R 6
垂直表示文字数
表示する文字行数を指定する。
25
25
R 7
垂直同期位置 (一 1)
垂直同期信号を出力する位置(文字数)を指定する。
28
28
R 8
インタレース,スキユー
ラスタスキャンモード指定. DISPTMG 信号 • CUDISP
信号のスキュー(運れ)を指定する。
0
0
R 9
最大ラスタァドレス
1行を構成するラスタ数(走査線)から1引いた値を指定する。
D
mm
( R 10)
カーソルスタートラスタ
カーソル形状,表示モードの指定。
■
B
( R 11)
カーソルエンドラスタ
XI では使われていない。
R 12
スタートアドレス上位
座標 (0,0) に対応するテキスト VRAM の値を指定する。
R 13
スタートアドレス下位
ただし VRAM は0000 „~07 FF „ 番地に対応する。
■
( R 14)
カーソルアドレス上位
カーソルの表示アドレスを指定する。
( R 15)
カーソルアドレス下位
XI では使われていない。
■
■
■■■
( R 16)
ライトペン上位
ライトペン栈出アドレスを K 憶する。
一
—
( R 17)
ライトペン下位
XI では使われていない。
1800 „番地に〇〜 17 を OUT すれば AR に値を設定できる。その後, 1801 H に OUT すれば
R0 〜 R17 に値を設定できるわけだ。
R0 (0 〜 255)
R1(0 〜 255)
R2 (0 〜 255)
R0 (水平総文字数)は水平走査周期を文字数に換算したものから 一 1 したものであ
る。総文字数というのは「実際に表示されている1行の文字数」+「水平帰線時間を文字数
に換算した値」のことである。 R 1 は表示文字数。これが「実際に表示される1行の文字数」
である。 R 2 は水平同期位置から 一 1したもの(これも文字数に換算する)。
R3 (0 〜 255)
この 1 バイトは 上位 4 ビットと 下位 4 ビットの二つに 分かれて意味を持つ。下位 4 ビッ
卜は 水平同期信号の パルス 幅を文字数に換算した もの。 XI では 40 桁で 「 4 」, 80 桁で 「 8 」
を使って いる。 上位 4 ビットは 垂直同期 パルス 幅を ラスタ 数に換算した ものである。 同様
34 试験に出る XI
図 1-1 CRTC 内部レジスタの意味
水平総文字 数 ( R0+1)
▲ —
水平 同期 位 S(R2+1)
-^
==1
水平表示文字 数 ( R1)
w
|
• - _ ■ •
1 1 1
水平 殊線期間
•
1 1 1
1 I
1 1 1 ,
画像表示 期間
垂直帰 線 期間
はスタ数=_
紇ラスタ調整 ( R 5)
に XI では低解像度モニタ(標準解像度モニタ)に対しては「3」, turbo での高解像度モ
二夕に対しては「8」を指定する。ところでいきなり「ラスタ」という言葉が出てきた
が,これは「走査線」のことと思って差し支えない。ほら,200ラインのディスプレイをよ
一く見ると200本分の横縞が見えるであろう。アレである。
R4 ( 0 〜 127)
R6 (0 〜 127)
R7 ( 0 〜 127)
R 4 は R 0, R 6 は Rl , R 7 は R 2 と対応している。すべて文字数に換算して設定する。
R5 (0 〜 31)
これは垂直方向の帰線周期の微調整である。 R 4 は文字数だが, R 5 はラスタ本数,すな
わち走査線の本数で指定する。このレジスタはスーパーインポーズ時のスムーススクロー
ル ( BASIC のスクロール命令)と関係している。第0章の8255②: 1 A 02„ の説明を参照の
こと。
R8
表 1-2 から分かるように,ビットごとに別々の意味を持つ。 XI を普通に使う場合には常
に0でよいが,それ以外の値を設定することも可能である。
インタレースモード(ビット1, 2)
普通はノンインタレースモードである。インタレースシンクモードにすると画面が微妙
に褽えて,目を悪くするにはうつてつけである。インタレースシンク&ビデオモードにする
と,画面は縦にぐしやつと潰れる(本当は潰れるだけではない)。そして, R 5 を調節しな
垂
直
総
文
字
数
R 4
+
1
1
垂
直
同
期
位
置
|
R 7
+
1
垂
直
表
示
文
字
数
R 6
い
'
第1章 CRTC 35
R 8 の機能
7 6 5 4 3 2 1 0
□
□
E1
■
□
B
インタレ
ースモード
, 、
1
V
S
ラスタスキヤンモード
0
0
)
,ノンインタレ-
_スモード
1
0
J
0
1
インタレースシンクモード
1 1
インタレースシンク&ビデオモード
DISPTMG スキュービット
D,
Do
DISPTMG 信号
0
0
スキューなし
0
1
1 文字スキュー
1
0
2 文字スキュー
1
1
出力されない
カー
ソルスキ ユー ビット
C,
Co
CUDISP 信号
0
0
スキューなし
0
1
1 文字スキュー
1
0
2 文字スキュー
1
1
出力されない
いと画面が上下にくるくる流れるであろう(垂直同期がずれるのだ)。
DISPTMG 信号(ビット5 , 4 )
普通はスキューなしのモードが設定されている0スキューを指定した場合は左端の1文
字,もしくは2文字が CRT の右端に行ってしまう。その他の文字は移動しない。「11」で「出
力されない」を指定すると,画面には何も現れなくなる。
CUDISP 信号(ビット7,6 )
XI ではこの信号はオーブン(無接続)になっているので,ここをいじっても何も起こら
ない。同じ CRTC を使っていた PASOPIA 7 ではこの機能を使って力ーソルを出してい
た。
R 9 (0 〜 31)
最大ラスタアドレスというのは, 「1 文字を何ラスタで表示す るか」 なのだ0 R9 にはそ
の数 一 1 を設定す る 。XI では文字は8ラスタで表示され るから 7を指定す る 。 turbo では
7 か 15,そしてアンダーラインモードのときは,アンダーラインの分も入れるので,9 か
19となる。
R 10 ( 0〜 127), R 11( 0〜 31)
XI では一切使っていない。カーソルの形状,モードの指定に使われる。
R 12 ( 0〜 63)
R 13 ( 0〜 255)
36 試験に出る XI
二つのレジスタを合わせた 14 ビットで表示開始アドレス(左上端に表示するキャラク
夕のテキスト VRAM のアドレス)を指定する。 XI では2048バイトの RAM (キャラク
夕表示用)しか持っていない。これは2進数では & B 00000000000 〜 & B 11111111111
(11 桁)であるから XI では R 12 は下位3ビットだけに意味がある0最初に例を挙げたリス
卜 1-1 の画面切り換えは, R 12, R 13 をいじっている。
R14( 0 〜 654), R15 ( 0 〜 255)
カーソルを表示するアドレスを指定する。 XI では使われていない。
R16( 〇〜 64), R17 ( 0 〜 255)
ライトペンの位置を読み取るためのレジスタである。 XI では使われていない。
ここで全体的な CRTC の解説の補足をしておく。
1) HD 46505 - SP の仕様では, R 0 〜 R 11 が書き込み可能, R 12 〜 R 15 が書き込み/読み込
みの両方が可能, R 16, R 17 が読み込みだけ可能となっている。ところが XI では読み
込みは一切できない。
2) CRTC の説明では「文字」で機能を説明した。グラフィックは,「同じ位置に表示さ
れる文字」と同様な扱いを受ける0つまり,スタートアドレスを変えたならば,グラ
フィックも同様に表示が移動する。たとえば,テキストの3000„番地と, G - RAM の
4000„,4800,“ 5000„,5800„,60006800„,7000„,7800„ の8バイトは , CRTC を
いかに設定しようとも重なり合って表示される。
以上である0ここらで気分転換に リスト 1-3 を打ち込んで遊んでいただきたい。このプ
ログラムは R 12, R 13 をいじつてグラフィックを上下左右に8ドット単位でスクロールさ
せるものである。 VRAM には触らずに, CRT 上での表示位置(表示開始アドレス)を動
かすことによつてスクロールを実現している。念のために注意しておくが,これは「見て
面白い」のであつて,あまり実用にはならない。また,時々ちらつきが出るが,それは垂
直帰線期間の間(つまり画面に何も表示され ていない 間)を考慮せず, R 12, R 13 を設定して
いるからである。その気のある人はリスト 1-2 を参考にして正しく機械語で組んでみてい
ただきたい。
リスト 1-3 ハー ドウ エアスクロールもど洚
INIT:WIDTH 80:CLS 4:WIDTH 40
GRAPH 0,0
FOR J=1 TO 7:CIRCLE (280,160),J»5
Y= 0:FOR X= 0 TO 30 : GOSUB
X=30:FOR Y= 0 TO15 : GOSUB
Y=15:FOR X=30 TO 0 STEP -1 : GOSUB
X= 0 : FOR Y=15 TO 0 STEP -1:GOSUB
GOTO130
: NEXT
START"
START"
START"
START”
: NEXT
: NEXT
: NEXT
: NEXT
256
LABEL "START"
A=X+Y*40 : A1=A ¥ 256 : A2=A MOD
1 GRAPH 0,0
OUT &H1800,12:OUT &H1801,A1
OUT &H1800,13:OUT &H1801 f A2
RETURN
CRTC
さらに0闩丁(3%究《3
リスト1-4, 1-5 は画面モードのサンブルである0
リスト 1-4 XI 用画面サンプル
100 INIT : CIRCLE( 200 f 100),90
110 RESTORE "4025 じ .
120 FOR Z=1T0 8 : GOSUB M MAIN if : BEEP : WHILE ( INKEY$ ( 0 ) = ff tf ) : WEND
130 NEXT:END
140 1
150 LABEL M FOO t# : WIDTH80 : RESTORE #f 8025L ff : GOSUB ff MAIN ••: BEEP
160 INPUT A$:ON ERROR GOTO 190:RESTORE A$:ON ERROR GOTO 0
170 GOSUB if MAIN ff :END
180 1 ERROR TRAP
190 PRINT "ILLIGAL LABEL ••: BEEP : END
200 1
210 LABEL "BAR ”: WIDTH 80: RESTORE tf 8025L M
220 GOSUB”MAIN ••: END
230 f
240 LABEL ff MAIN ff
250 GOSUB ff SETCRTC ••: GOSUB ## 80/4O ff
260 RETURN
270 1
280 LABEL"SETCRTC"
290 FORI=0TO13
300 HEAD D$:D=VAL(W + D$>
310 OUT&H18O0,I : •SET CRTC REG- No-
320 OUT&H1801 f D:•SET DATA
330 NEXT:RETURN
340 1
350 LABEL M 80/4O tf
360 READ D$:D = VAL( ,f &H #f + D$)
370 OUT&H1A03. D
380 RETURN
390 f
400
LABEL 9
4025L f,
: DATA
37
28
2D
34
IF
02
19
lC f 00,07 ,00,00,00!00 t 0D :
1 40
25
410
LABEL.
4020 じ
: DATA
37
28
2D
34
18
08
14
16,00,09,00,00,00100,00 :
1 40
20
420
LABEL 1
4012 じ •
: DATA
37
28
2D
34
0F
02
0C
0E f 00 f 0F f 00 f 00,00,00,0D :
M0
12
430
440
LABEL 9
9
4010L°
: DATA
37
28
2D
34
OB
12
OA
0B f 00,13 f 00 f 0O f 00,0O f 0D :
f 40
10
450
LABEL'
8025 じ
: DATA
6F
50
59
38
IF
02
19
1C,00 t 07 f 00 f 00 f O0 f 00 f 0C :
*80
25
460
LABEL 9
8020L #i
: DATA
6F
50
59
38
18
08
14
16,00,09,00,00,00,00,00 :
1 80
20
470
LABEL 9
8012 じ .
: DATA
6F
50
59
38
0F
02
0C
0E f 00 f 0F f 00,00 f 0O f 00 f OC :
1 80
12
480
490
LABEL
9
80101 ,
: DATA
6F
50
59
38
0B
12
0A
0B f 00 t 13 f 00 f 00,00,00 f 0C :
1 80
10
500 LABE!/ f Q8006L f •: DATA 6F f 50 f 59 f 38 f 07 f 02 t 06 f 07 f 00 f 1 F f 00 f 00 f 00 f 00 f 0C : 1 80 t 06
510 LABEL # , Q8005L tf :DATA 6F t 50 f 59 f 38 f 06 f 02 f 05 f 05 f 00 f 27 f 00 f 00 f 00 t 00 f 0C : 1 80 f 05
520 LABEL f# Q8005D ft : DATA 6F f 50 f 59 f 38 f 06 f 04 f 05 f 05 f 00 f 2F f 00 f 00 f 00 f 00 f 0C : 1 80 f 05
530 LABEL M Q8003L M :DATA 6F f 50 f 59 f 38 f 03 f 02 f 03 f 03 f 00 f 3F f 00 f 00 f 00 f 00 f 0C : 1 80 f 03
リストレ5 XIturbo 用画面サンブル
100 INIT : CIRCLE(200 f 100) f 90
110 RESTORE "4025L”
120 FOR Z=lT018 : GOSUB f , MAIN ft : BEEP : WHILE( INKEYS ( 0 ) = ° M ) : WEND
130 NEXT:END
140 1
150 LABEL 11 FOO ••: WIDTH80 : RESTORE #t 8025H tf •• GOSUB f .MAIN" : BEEP
160 INPUT AS:ON ERROR GOTO 190:RESTORE A$:ON ERROR GOTO 0
170 GOSUB #t MAIN ff :END
180 1 ERROR TRAP
190 PRINT "ILLIGAL LABEL" : BEEP:END
200 1
210 LABEL f# BAR M : WIDTH 80 : RESTORE ff 8025H #t
220 GOSUB..MAIN ••: END
230 1
240 LABFL tf MAIN f#
250 GOSUB”SETCRTC" :GOSUB"80/40” •• GOSUB M 1 FD 拿 ”
260 RETURN
270 1
280 LABEL ft SETCRTC ff
290 FOHI=0TO13
300 READ D$:D = VAL( M &H ft + D$)
38 試験に出る XI
310 0UT&H1 800,1: f SET CRTC REG* No-
320 OUT&H1801 f D: 1 SET DATA
330 NEXT-.RETURN
340 1
350 LABEL ff 80/40 ff
360 READ D$:D = VAL( ft &H ff + D$)
370 OUT&H1A03,D
380 RETURN
390 1
400 LABEL 11 lFDt M
410 READ D$:D = VAL( ft &H ft -fD$)
420 OUT &HlFD0 f D
430 RETURN
440 1
450 LABE じ • 4025 じ •: DATA 37 t 28 f 2D f 34 t 1F f 02 f 19 f 1C f 00 f 07 f 00 f 00 f 00 t 00 f 0D f 00 : 1 40 f 25
460 LABEL ff 4020L , •: DATA 37 f 28 f 2D f 34 f 18 f 08 f 14 f 16 f 00 f 09 f 00 f 00 f 00 f 00,0D f 80 : 1 40 f 20
470 LABEL M 4012L M :DATA 37 f 28 f 2D f 34 f OF f 02 t 0C f 0E f 00 t 0F f 00 f 00 f 00 f 00 f 0D f 04 : 1 40 f 12
480 LABEL”4010 じ •: DATA 37 f 28 f 2D f 34 f 0B f 12 f 0A f 0B t 00 f 13 f 00 f 00 f 00 f 00,0D f 84 : f 40 f 10
490 1
500 LABEL ff 8025L ,f :DATA 6F f 50 f 59 f 38 f IF t 02 f 19 f 1C , 00 f 07 f 00 f 00 f 00 f 00 f 0C f 00 : 1 80 f 25
510 LABEL M 8020L ••: DATA 6F f 50 f 59 f 38 f 18 f 08 f 14 f 16 f 00 f 09 f 00 f 00 f 00 f 00 f 0C f 80 : 1 80 f 20
520 LABEL tf 8012L tf :DATA 6F f 50 f 59 f 38 f 0F f 02 f 0C f 0E f 00 f 0F f 00 f 00 f 00 f 00 f 0C f 04 : 1 80 f 12
530 LABEL ff 8010L ••: DATA 6F t 50 f 59 f 38 t 0B f 12 f 0A f 0B f 00 f 13,00 f 00 f 00 f 00 t 0C t 84 : 1 80,10
540 1
550 LABEL ff 4025H ff :DATA 35 f 28 f 2D f 84 f 1 B f 00 f 19 f 1A f 00 f 0F f 00 t 00 f 00 f 00 f 0D f 03 : 1 40 f 25
560 し ABE じ M025M ••: DATA 35 f 28 f 2D f 84 f 1 B f 00 f 19 f 1A f 00 f 0F f 00 t 00 t 00 f 00 f 0D f 0 1: 1 40 f 25
570 LABEL M 4O20H ,f :DATA 35 f 28 f 2D f 84 f 15 f 08 f 14 t 15 f 00 f 13 t 00 f 00 f 00,00 f 0D f 81: f 40 t 20
580 LABEL ft 4012H ••: DATA 35 f 28 f 2D f 84 f 0D f 00 f 0C f 0D f 00 f 1F f 00 f 00 f 00,00 f 0D f 07 : 1 40,12
590 し ABE し •• 401 0M ••: DATA 35 f 28 f 2D f 84 f 0D f 00 f 0C f 0D f 00 f 1 F f 00 f 00 f 00 t 00 • 0D f 05 : 1 40 f 1 0
600 1
610 LABEL ff 8025H , •: DATA 6B f 50 f 59 f 88 t 1 B f 00 f 19 f 1A f 00 f 0F f 00 f 00 t 00 t 00 f 0C f 03 : 1 80 t 06
620 LABEL ft 8025M ••: DATA 6B f 50 f 59 f 88 f 1B f 00 f 19 f 1A f 00 f 0F f 00 f 00 t 00 f 00 t 0C f 0 1: 1 80 f 06
630 LABEL fi 8020H ,f :DATA 6B f 50 f 59 f 88 f 15 f 08 f 14 f 15 f 00 f 13 f 00 f 00 f 00 t 00 f 0C f 81: 1 80 f 05
640 LABEL M 8012H ••: DATA 6B f 50 f 59 f 88 f 0D t 00 f 0C t 0D f 00 f 1F t 00 f 00 f 00 f 00,0C f 07 : 1 80 f 05
650 LABE じ • 8012M":DATA 6B t 50 f 59 f 88 f 0D f 00 f 0C f 0D f 00 f 1F f 00 f 00 f 00,00 f 0C f 05 : f 80 f 03
まずリスト 1-4 から解説しよう。これは XI 用であるが,当然のことに CZ -8 FB 01 を使
って200ラインモードの画面であれば turbo でも使える。 RUN させたなら,何かキーを押
すたびに8とおりの画面モードが出現する。終わったなら,
” BAR ¢3
と打ち込むと正常な画面になる。ただし,打ち込み間違いがあると表示がめちゃくちゃに
なるので, RUN させる前にセーブしておくべきである。
このブログラムの中心は400〜480行のデータ文である。サブルーチン* MAIN " は14個
のデータを CRTC の内部レジスタ R 0 〜 R 13 までに設定する。最後の 0 D H もしくは 0 C „ は
8255に OUT されるデータである。これはビットセット/リセットモ ー ドを使っている。1/
0の 1 A 02„ 番地のビット6を操作しているのだ。第0章の I / O マップを参照していただき
たい。
XI における正常な40桁,80桁の画面はそれぞれ ''4025 L " と10251/に対応してい
る0だから,それ以外のモードのときは実に楽しくシュールである。
これ以外の使い方としては, 「’’ FOOcJ 」 と打ち込むと,画面に「?」が出て入カモード
になるはずである。このときラベル名を入れるとそのラベルの直後にあるデータを使って
画面モードを設定することができる(たとえば? Q 8006 L «5)。このときは500行以降のデ
一夕も使えることになる。シュールさを味わって欲しい。ただし R 5 の値が微妙であるか
ら,場合によっては垂直同期などがずれて,表示が流れる可能性がある。いろいろ試して
みるのも面白いかもしれない。
次に turbo 用のリスト 1-5 である。こちらの方は,1行中のデータが一つ増えている。
第1章 CRTC 39
これは 1 FD 0„ (画面管理ポート)への出カデータである。問題になるのはビット〇〜2と
7である。表 1-3 を見て納得していただきたい。
以上が基礎編である。
表 1-3 画面モードと画面管理ボート ( IFDOh )
低解像 •'
SSSSmw —
ちっと表示すあ 3
XI で表示できる文字数は,最大で 80 X 25 の2000文字であると一般に信じられてい
る。しかし,その認識は甘いのである。次のブログラム,リスト 1-6 は 81 X 25, 82 X 25 の
画面モードを作ってしまうのだ。それぞれの場合について,よ一く文字数を数えてみてい
ただきたい。最後の1行は途中までしか表示していないが,これは BASIC 上でやっている
ので,勝手にスクロールさせないためなのだ 0 アドレスを計算して POKE @ や OUT 文を
使えばきっちり表示する(その場合はアトリビュートの設定も忘れずに)。
リスト 1-6 WIDTH 81
100 KEY 2,”WI.80"+CHR$(13)
110 L=81 : 1 OR L=82
120 INIT:WIDTH 80:CLS 4
130 OUT &H1800,1:OUT &H1801 t L
140 FOR 1 =1 TO 24:PRINT STRINGS ( L f CHRS ( 64 -f I ) ) : : NEXT
150 PRINT STRING$<80-<L-80>*25-l , CHR$<64+25>>;
160 GOTO160
には'' WI . 80" を定義してあるから,まともな画面に戻すときに使って欲しい。た
だし turbo の場合は, CZ -8 FB 01 を使うこと。それから, CRT の調節の具合によって
は,右端が画面からはみ出してしまうことがあるかもしれない。そのようなときは素直に
納得していただきたい。
実行してみると分かるが , L = 82 で1行82文字にしたとき,右下に「!」が2個表示さ
れる。これはなぜかというと, 82 X 25 = & H 802 = & H 800+ 2だからなのである。す
なわち, CRTC は2050個の文字を表示しようとして,ともかくも2048個目まではど一っ
と表示するのである。ところがどっこい,テキスト VRAM はそこで終わりなので , CRTC
は仕方なくテキスト VRAM の先頭に戻って2文字分をもう一度表示し,その場をつくろ
うのである。そう, CRTC はどんな挑戦でも受けているのである。
40 試験に出るXI
全画面 T あ 3
最後にビデオマニアのために全画面ワイプ用のブログラムをリスト1- 7 に示しておく。
これは turboZ のオーバースキャンみたいなものと考えて差し支えないであろう。し
つこいようだが turbo BASIC では動かないので, CZ-8FB01 を使っていただきたい。
リスト 1-7 全画面ワイプ
100 GOSUB M BAR M : 1 INITIALIZE
110 GOSUB M PCGDEF M : f PCG DEFINITION
120 WIDTH80:CLS4 : INIT
130 RESTORE"ALLWP M :GOSUB°MAIN ••ゾ SET CRTC
140 CGHN1 : C0L0R7 : , WIPE COLOR = 7 (WHITE)
150 FOR 1=0 TO 8 : CLS f I : PAUSE1 : NEXT
160 FORI=8TO0STEP-1 : CLS f I : PAUSE 1:NEXT
170 IF INKEY$(0) = tftf THEN 150
180 GOSUB t# BAR M : END : 1 CRT=NORMAL AND END
190 1
200 LABEL #t BAR ,f : INIT : CLS f 32 : WIDTH40 : RESTORE" 1 4025L ,f
210 GOSUB ff MAIN ••: RETURN
220 1
230 LABEL..MAIN"
240 OOSUB #, SETCRTC if : GOSUB f# 8O/40 M
250 RETURN
260 1
270 LABEL"SETCRTC”
280 FOR I=0TO13
290 HEAD DS:D = VAL("&H" + D$ >
300 OUT &H1800 f I : f SET CRTC RKG- No.
310 OUT &H1801 f D: f SET DATA
320 NEXT:RETURN
330 1
340 LABEL ff 80/40 ,f
350 READ D$:D = VAL( f# &H #, ^D$)
360 OUT &HlA03 f D
370 RETURN
380 f
390 LABF 丄 "ALLWP":DATA 37 f 2E t 30 f 34 f 1F f 02 f 1C f 1E t 00 f 07 f 00 f 00 f 00 f 00 f 0D : 1 46 f 28
400 LABEL” 40251/•: DATA 37 f 28 f 2D f 34 f 1F f 02 f 19 f 1C t 00 f 07 f 00 f 00 f 00 f 00 f 0D : 1 40 f 25
410 1
420 LABEL 11 PCGDEF fi
430 M=&HFF
440 FOR 1=0 TO 8
450 P$=STRING$(I t &H0)4STRINGS(8-I t M)
460 DEFCHR$(I>=P$+P$+P$
470 M=INT(M/2)
480 NKXT:RETURN
ブログラムの最初のイニシャライズで CRTC を正常にしているのは, PCG 定義をするた
めである。 PCG を定義するためには, CRTC が正しく普通のモードになっている必要が
あるのだ。詳しくは第2章の PCG を参照していただきたい。さて,ブログラム中に
CLS , I
という命令が出てくるが,これは CZ -8 FB 01 の隠れ命令で, I の値を ASCII コードとする
キャラクタをスペースとみなして画面をクリアするのである。一度この命令が実行される
と,そのキャラクタが論理上のスペースとみなされるので,普通の女の子に戻ってまとも
な CLS をしたいときは,
CLS , 32
を実行する必要がある。これは turbo BASIC では削られている機能である。
このプログラムを実行すると,やがて画面は46字 X 28 行モードになる。しかし BASIC
は 80 X 25 のモードのつもりで動いている。これによって 「 CLS , I 」を実行すると,46文
第1章 CRTC 41
字 X28 行をすべてキャラクタ = CHR $( I ) で埋めてくれる。プログラムはキーが押される
までワイプを繰り返す。何かキーが押されたなら,画面を正常にして終了する。打ち込み
間違いをすると画面がぐちゃぐちゃになるので注意すること。なお,このプログラムはス
ーパーインポーズ用である。スーパーインポーズでないときは画面の下の方に少し隙間が
できているが,スーパーインポーズにすると,びよ一んと伸びてくるのだ。これぞまさし
く 東洋の 神秘と言わざるを得まい。
この章のサンブルブログラムでは充分に示せたかどうか分からないが, CRTC という石
はかなり面白い。たとえば画面を 20X25 にして 4 面に分けて使うとかができる。しか
し,実際に実用に値する裏技はあまりなく,私が考えついたのはリスト 1-7 の全画面ワイ
ブぐらいなのである。これは,裏技は所詮裏技にすぎないということなのであろうか?
しかし XI の CRTC はいじろうと思えばいじれるのである0そ 一 なればとことんいじり
回すのがその筋のその筋たるゆえんなのである。
42 試験に出る XI
第 2 章
PCG は二度劣いレいの I おる • •
この章では PCG をやるのである。念のために言っておくと, PCG とは Programmable
Character Generator の意味である。ここで言う Programmable とは「書き換えられるよ
一ん」ということ。そして Character Generator とはそのままだと, 「文字 生成機」とい
うことになる。 文字 生成機とは実に面妖であるが,つまりは「この ASCII コードの 文字
は,こ一ゆーパターンになっているのだ」ということを決めるものなのだ 。 Programmable
でない場合は,そのパターン ( FONT : フォン ト)は ROM になっているわけである。そ
のような背景があるので, PCG は場合によっては , RAM CG などと呼ばれることもある
のである。それの反対は ROM CG である。
さて,周知のよ一に XI や MZ - 2500ではこの PCG がとてもパワフルなので , XEVIOUS
やグラディウスなどがバシバシと動くのであった。 PCG の利点は,(アトリビュートも入れ
るとすると)2バイトのデータを転送するだけで,8ドット x 8ドット x 8色のパターン
を移動させることができる,ということにある。グラフィックでやるなら,24バイトの転
送であるから,単純に考えれば12倍の速度である。もし,アトリビュートを移動しなくて
よいなら(多くの場合そうなっている),24倍の速度ということになる。しかもグラフィッ
クと PCG の重ね合わせが自由だったりするので,1バイトで二度おいしいのである。ゲー
ム製作者にとっては,これはまさしく,棚力ゝら PCG , もしくは,鴨が PCG を背負ってき
た,と言えよう。
しかし, PCG といえども完全にグラフィックと置き換えられるわけではない。すなわ
ち, PCG は256個しか使えないし,表示位置も8ドット単位でしか指定することができな
いのである。
以上のよ一なことを踏まえつつ,話は佳境に入ってゆくのであった。
PCG 负基本技
BASIC 上で PCG を使うには,まずは PCG を定義しなければならない0その後でモード
を切り換えて表示するのである。すなわち, CZ -8 FB 01, 8 CB 01 では,
10 INIT : CLS
20 DEFCHR $(77)=24 バイトの文字列
30 CGEN 1
40 PRINT CHR $(77)
である。当たり前であった。
これを機械語的にやると,30〜40行は大体,
30 OUT & H 2800, & H 27
44 试験に出る XI
40 OUT & H 3000 , 77
となる。やっていることは完全に同じではない点を注意していただきたい。
さて,30行の OUT 文はアトリビュートの設定である。アトリビュートの意味は第0章
にも載せたが,ここでも 図 2-1 に示しておく。これにより, & H 27 とは色が7であり,か
つ PCG であるということが判明するであろう。40行の77は単なる ASCII コードなわけ
だ0
図 2-1 アトリビュート内のビットの意味
7 6 5 4 3 2 1 0
キャラクタ色 (0 〜 7)
色反転 ( = 1)
点滅 ( = 1)
CG (=0)/ PCG ( = 1)
垂直方向2倍モード ( = 1)
水平方向2倍モード ( = 1)
アトリビュートを他のものにすれば,それぞれ横2倍,縦2倍,反転などなどになる。
カラーを7以外にすると, PCG の色が変化する0たとえば リスト 2-1 のように ASCII コー
ド77の PCG に,
青は A , 赤は B, 緑は C
と定義しておいて,色を〇〜7まで変化させて表示すると,それなりのパターンが表示さ
れる。試していただきたい。
リスト 2-1 PCG とアトリビュートの カラー
100
WIDTH 40
110
A$ = ""
120
FOR I=&H41 TO &H43
130
A$=A$+LEFTS(CGPATS(I) f 8)
140
NEXT
150
DEFCHR$(77)=A$
160
FOR 1=0 TO 7
170
OUT 4H 30004 -I,77
180
OUT &H2000+I,&H20+I
190
NEXT
200
LOCATE 0,5
PCG 访定親
BASIC では, PCG の定義には DEFCHR $ 文を使うわけである。 turbo では問題はないの
だが, XI では DEFCHR $ は異常に遅い命令として津々浦々に知れ渡っている。以下に,な
にゆえにそのよ一に遅いのかを示しつつ,超高速 PCG 定義などへと到達する予定であ
る。
まずは手っ取り早く,機械語で PCG を定義するブログラムを リスト 2-2 に示す。 リスト
第2章 PCG 45
2-3 は例によって, BASIC からの使用方法である0リスト2-2, 2-3 は極めて基本技であ
るから,あくまでも学習用ということを心得ておいていただきたい。
リスト 2-2 を説明するに先立って, PCG 定義の原理を説明しておこう。
第1章でも示したように, XI の画面表示は CRTC ( CRT コントローラ)が取り仕切っ
ているのである。ここでちょっと脇道にそれて, CRTC がど 一 やって文字を表示している
のかを,てきと一に考えてみるのである。 CRTC はまず画面の左上から,横に走査線1本
分(ラスタという)を表示するのである。 CRTC は書き始めるに先立って, VRAM を見る
のである(ここらへんは,極めていい加減な表現だから注意)。まずは左上の LOCATE
0, 0の位置だから, I / O 空間の300 0 H 番地にある VRAM の ASCII コードを見るわけ
だ。ここでは 「 A 」 つまり CHR $(& H 41) が VRAM に書いてあるとしよう0すると CRTC
は 「おっ! 41„だな0それでは,キャラクタジェネレータの4 しに 対応するところから パ
ターンを持ってきて表示しましょう」 とつぶやくのである。ただし, 「 A 」 という文字は8 x
8ドットだから「上から何段目」ということも指定しなければならない。 CRTC はそこん
とこもちゃんと心得ていて, 「 ASCII コード 41 H の0段目のパターン」というように指定し
てくるのである。この8ドットを表示した後は 「 VRAM の300 1 H 番地に書かれている
ASCII コードの文字の0段目のパターン J , ……と続くのである。そして,右上の端まで行
ったら,同じ ASCII コードに対して段数を増加して2本目を左端から表示するのであ
る0
注目して欲しいのは,これらの途中で, 「 CRTC が CG のパターン(データ)にアクセス
している」ということである。つまり,
CRTC はパターンが格納されている ROM や RAM にアクセスしている
のである。そこで PCG が,ある VRAM にアクセスしているとき,その VRAM に定義の
対象になる ASCII コードを用意しておくと, CRTC は律儀にその ASCII コードに対応す
る CG ROM (または RAM ) にアクセスする。そのタイミングをねらって, 別の回路から
データを送ってやり,パターンを害き込んでしまう のである。これが XI における PCG 定
義の仕組みである。
以上が原理なのだが,よ一く考えてみると落とし穴があるのだ。どこにあるかという
と, PCG が CRTC にアクセスされてデータが読み出されている最中に,横からシャシャリ
出てきて,その PCG に読み書き動作をするなど許されないということなのだ。普通のメモ
リに対して「読むことと書くことを同時に行なう」のは許されないのである(現在はデュ
アルポート RAM といって,それができる RAM もあるが)。
では,本当のところはど 一 やっているのかというと,
CRTC か # 「表示されない VRAM 」 にアクセスしているときだけ,他の回路からのデータ
R / W を許している
のである。
そのココロは, VRAM は3000 H 〜37 FF H = 2048バイトあるのに,画面表示に使われてる
VRAM は,普通は,最大で 80 X 25 = 2000 バイトで,48バイトが宙に浮いているというこ
となのである0 CRTC がその VRAM に空しいアクセスをしているスキをねらって,デー
46 試験に出る XI
夕の読み書きを行なうのである。その「表示はされないが, CRTC からアクセスされる
VRAM 」 というのは,
1) WIDTH 40 : SCREEN , 0の場合
I / O の 33 E 8 H 〜33 FF H までの24バイト
2) WIDTH 40 : SCREEN, 1の場合
I / O の 37E8 H 〜 37FF H までの24バイト
3) WIDTH 80の場合
I / O の 37 D 0„ 〜 37 FF H までの48バイト
の三つの場合がある。実際はそれぞれに対応するアトリビュート ( turbo の場合は,さらに
漢字 VRAM も)セットしておく必要がある。
そこでやっとリスト2-2, 2-3 の説明に入るのであった。
リスト 2-2 機械語による PCG 定義
.Z80
.PHASE 0E000H
E000
EB
w
EX
DE f HL
E001
46
LD
B f (HL) ;HI
E002
23
INC
HL
E003
4E
LD
C. (HU ;LOW
E004
23
INC
HL
E005
ED 43 E078
LD
(BCWORK) f BC
E009
56
LD
D t (HL) ;COUNT
E00A
23
INC
HL
K00B
5B
LD
E t (HL) ;ASCII
CODE
E00C
23
INC
HL
E00D
CD E018
•
CALL
SET0
E010
46
•
LD
B. (HU
E01 1
23
INC
HL ;HL POINTS PCG DATA
E012
0E 00
LD
C f 00H ; BC=1500H f 1600H or 1700H
E014
CD E052
CALL
SETPCG
E017
C9
•
RET
B018
E5
SET0 :
PUSH
HL ;SAVE
POINTER
E019
D5
PUSH
DE ;SAVE
COUNT and ASCII CO
DE
E01A
01 1FD0
LD
BC,1FD0H
;FOR turbo
E01D
AF
XOR
A
E01E
ED 79
•
OUT
(C) f A
E020
ED 4B E078
f
LD
BC,(BCWORK)
E024
〇 )
213800
LD
HL t 3800H
;KANJI VRAM(turb
E027
3E 00
LD
A.00H
E029
CD E048
■
CALL
SET1
E02C
ED 4B E078
t
LD
BC , < BCWORK)
E030
212800
LD
HL t 2800H
;ATTRIBUTE
E033
D1
POP
DE
E034
D5
PUSH
DE
E035
3E 20
LD
A f 20H
;PCG,COLOR=0
E037
CD E048
•
CALL
SETl
E03A
ED 4B E078
•
LD
BC,(BCWORK)
E03E
213000
LD
HL t 3000H
;VRAM
E041
D1
POP
DE
E042
7B
LD
A f E
;ASCII CODE
E043
CD E048
•
CALL
SETl
E046
El
•
POP
HL
E047
C9
暴
RET
E048
09
SET1 :
ADD
HL f BC
E049
44
LD
B f H
E04A
4D
LD
C.L ;BC=HL+BC
E04B
ED 79
SET2 :
OUT
(C) f A
第2章 PCG 47
E04D
03
INC
BC ;
INC ADDRESS
E04E
15
DEC
D ;DEC COUNTER
E04F
20 FA
JR
NZ f SET2
E051
C9
•
RET
E052
1E 08
SETPCG :
LD
E.08H ;
COUNTER
E054
D9
•
EXX
E055
F3
t
DI
E056
01 1A01
LD
BC,1A01H
E059
ED 78
VDISP0 :
IN
A, (C>
E05B
F2 E059
JP
P f VDISP0
E05E
ED 78
VDISP1 :
IN
A f (C)
E060
FA E05E
jp
M f VDISPl
E063
D9
7E
•
EXX
E064
SETP :
LD
A,(HL)
7,GET DATA
E065
ED 79
OUT
(C) f A
12, SET 1 BYTE
E067
23
INC
HL
BC
6, INC POINTER
E068
03
INC
6,INC I/O ADDRESS
;7+12+6.6:31
•
E069
00
9
NOP
4
E06A
23
INC
HL
HL
6
E06B
2B
DEC
6,DUMMY
;4+6.6=
16
E06C
3E 0D
t
LD
A,0DH
7
E06E
3D
DLY :
DBG
A
4
E06F
C2 E06E
JP
NZ f DLY
10
E072
1D
DEC
E
4
E073
C2 E064
JP
NZ f SETP
10
;7+(4 + 10”13 + 4 + 10 = 203
31+16+203=250
E076
FB
El
E077
C9
RET
•
E078
•
BCWORK : DS
2
END
リスト 2-2 で最初にやっているのは,パラメータの受け取りである。例によって DE レジ
スタを利用している0まずは DE レジスタの内容を HL レジスタに移して, BC レジスタに
格納している0これは先程説明した「表示されない VRAM 」 の先頭アドレス(相対値)で
ある。念のために害くが,なぜいちいち受け取っているかというと,そのアドレスは画面
モードによって違ってくるからである0その次に D レジスタに格納している 「 COUNT 」
も画面モードによって変わるのは同じことである。
次に肝心の ASCII コードで ある。これは以上の パラメータを 持って SET 0 をコールし
ている。 SET 0 では (1 FD 0„) —00 H としているが,これは turbo 用である。 turbo ではこ
こが画面管理を行なっており, XI と同じ動作をさせるためには,00„を OUT しておく必要
がある。ただしこれは念のためであって, XI モードで起動しておけば, IPL が自動的に 00 H
をセットしておいてくれるから深く悩む必要はない。それは次の漢字 VRAM でも同じ
で,3800 „ + BC レジスタから, D レジスタ分00„をセットしている。もし turbo でなかった
場合は,これは3000 H + BC レジスタ番地からの VRAM にセットされることになるが,そ
の場合は直後にまた VRAM へ ASCII コードをセットするので,ただ単にムダになるだけ
であって,画面が乱れるなどの悪影響はないので安心するよ一に。それからアトリビュー
卜も忘れてはいけない。こいつは 20 h をセットしているから,つまりはノーマルの PCG
で,色は0 (つまり透明)である。ここは 第 5ビットが立っていれば何でもよいので, 気
分によっては FF H などにしてもよいだろう。
48 試験に出るXI
SETO はこれぐらいで,次は御本尊の SETPCG である。まず E 010„ で,あらかじめ B レ
ジスタにパラメータを渡している点に注意。この時点で B レジスタには, 15 H , 16„,17„の
うちどれかが入り,それによって青,赤,緑のうちどれがセットされるかが決まるのだ。
図 2-2 を見て納得していただきたい。
図 2-2 CG, 漢字 ROM , PCG アクセス用 I/O ポート
f
XI,XI turbo コンパチアクセスモード
14+ * M
CG ROM アクセス
IN
1
15* *„
PCG BLUE アクセス
IN OUT
16* * M
PCG RED アクセス
IN OUT
17* *„
PCG GREEN アクセス
し
IN OUT
XI turbo 高速 アクセスモード
I
14*0 m 〜14* F „
CG. 漢字 ROM アクセス
IN
15*0 h ~15* F „
PCG BLUE アクセス
IN/OUT
16*0 M ^16* F„
PCG RED アクセス
IN/OUT
17 * 0 M 〜 17 * F m
PCG GREEN アクセス
IN/OUT
チェックポイント
turbo の 場合 • 丨 0 ボート 1FD* H の 第 5 ビットが 1 ならば 高速
アクセスモード, 0 ならばコンパチアクセスモード。
さて,よく見ると分かるよ一に,実はこの方式では,一度に1色分しかセットできない
のである0すなわち,正しく PCG をセットするには,このルーチンを3回呼び出さなけれ
ばならないのだ。この点を心得ておいて欲しいわけである。
では E 052„ からの SETPCG である。まず E レジスタに 08 H をロー ドしている。これはと
りもなおさず,キャラクタのデータが8段飾りであることに由来する。つまり08„というの
はカウンタなのである。その後 E 055„〜 E 062„ T 何やら行なっているが,これは「垂直帰線
期間信号の立ち下がり」 ( I / O ポート 1 A 01„ 番地の第7ビット)の検出なのである。「そんな
もんを検出して,一体ど 一 すんだ」と思うであろうが,これには「今から CRTC は例の表
示されない VRAM へアクセスを開始しま〜す」という意味があるのだ。よってこれが GO
サインなのである。ところで,見慣れない条件 JP があるが,これは各自で自習していただ
きたい。
いよいよ核心中の核心が, E 064„ からである。まず, ( BC ) へ1バイト OUT してい
る。これで PCG セットが1段分できたことになる。 E 067„ までは実にありふれたブログラ
ムである0そして,出ました,ディレイルーチンである。ブログラムの右端に並んでいる
のは,ステート数(クロック数: XI は 4 MHz だから1クロックが 0.25 //s = 0. 00000025
秒)である。ループ1回分が250クロックになるようにしてある。なぜこのよ一になって
いるかというと,これは CRTC の都合によるものなのだ。すなわち 「 PCG のセットは
CRTC が表示されない RAM にアクセスしているときを利用する」という大原則があるの
で, 「 CRTC 様が次の段にアクセスなされるとき」をひたすら待たなければならないのであ
る。なぜ250クロックかというと,これは映像信号の水平周期 = l 5.98 kHz からきている
第 2 章 PCG 49
のだ。すなわち,
is . gslkHzT ^ 0 - 0000625 (秒)
_ 250 ( クロック )_
- 4(MHz)
なのだ。 15.98 kHz というのがどこから出てきたかというと,資料に書いてあつたからな
のだ。私は深く追及する気はないので,さっさとリスト 2-3 の説明に入つてしまうのであ
リスト 2-3 低速 PCG 定義
100
CLEAR &HE000
110
MEM$(&HE000 f 16)=HEXCHR$( tf EB 46 23 4E 23 ED
43
78 E0
56
23
5E
23
CD
18
E0*
)
120
MEM$(&HE010 f 16)=HEXCHR$( tf 46 23 0E 00 CD 52
E0
C9 E5
D5
01
D0
IF
AF
ED
79.
)
130
MEM$(&HE020 f 16)=HEXCHR$( ff ED 4B 78 E0 21 00
38
3E 00
CD
48
E0
ED
4B
78
E0 f
)
140
MEM$(&HE030 f 16)=HEXCHR$( M 21 00 28 D1 D5 3E
20
CD 48
E0
ED
4B
78
E0
21
00 f
)
150
MEM$(&HE040 t 16)=HEXCHR$( ff 30 D17B CD 48 E0
El
C9 09
44
4D
ED
79
03
15
20 f
)
160
MEM$(&HE050 f 16)=HEXCHR$( ff FA C9IE 08 D9 F3
01
011A
ED
78
F2
59
E0
ED
78.
)
170
MEM$(&HE060 f 16)=HEXCHR$( f# FA 5E E0 D9 7E ED
79
23 03
00
23
2B
3E
0D
3D
C2 f
)
180
MEM$(&HE070 f 16)=HEXCHR$( ff 6E E0 ID C2 64 E0
FB
C9 00
00
00
00
00
00
00
00 #
)
190
DEFUSR0=&HE000
200
9
210
CGEN 1:LOCATE 0,0
220
FORI=0TO255:PRINT #0 f CHR$( I ) ; •• NEXT: PRINT
230
CGEN 0
240
250
TIME=0
260
FORI=0TO255
270
A$ = USR0(CHRS(&H7 f &HD0 ,48 , 1 H15)♦STRINGS(8 f
&H3))
280
A$=USR0(CHR$(&H7 f atHD0 f 48 f I,&H16)^STRING$(8 f &HC))
290
A$ = USR0(CHR$(&H7 t &HD0•48•I•&H17 >♦STRINGS(8 f &H30))
300
NEXT
310
PRINT TIME
320
TIME=0
330
FORI=0TO255 : DEFCHRS(I)=STRING$(24 f 0) : NEXT
340
PRINT TIME
350
i
360
, A$=USR0(CHR$(&H7 f &HD0 f 48 f ? f &H??)^STRINGS(8 f
&H??))
: WIDTH
80
370
• A$ = USR0(CHR$(&H7 f AHE8 f 24 f ? f &H??)^STRING$(8 f AH??))
: WIDTH
40
: SCREEN ?
380
1 AS = USR0(CHR$(&H7 f &HE8 f 24 f ? t &H??)-fSTRING$(8 t
&H??))
: WIDTH
40
: SCREEN ?
•i
まず 210 〜 230 行ですベての PCG を表示しておく。次に 260 〜 300 行ですベての PCG を
3 色縦縞にしてしまう。 CHR$ (△) の中のパラメータは, WIDTH 80 のときのものであ
る(他のスクリーンモードのときは 360 行からの注釈文を見ておくれ)〇そして,すぐ後で
は DEFCHR$ 文で同じようなことをやっている。結局は速度比較なのである。で,その速
度はど 一 かというと,これがなんと同じで,両方とも 256 個の PCG を定義するのに 13 秒
前後かかっているのである。考えてみれば, CRT の垂直同期周波数は 60Hz 前後であ
る。つまり, 1 秒間に 60 回 PCG をセットするチャンスが来るわけだ 〇 256 個セットするに
は, 1 個当たり青赤緑の 3 回のチャンスが必要だから, 256X3 = 768 回のチャンスが必要で
ある。そいでもって, 768 + 60 = 12.8 (秒)かかってしまうのである。
そこで出てくるのが, 3 倍速 PCG 定義ブログラムであった。
PCG 勿高速定義
まずは, 3 倍の速さにするのである。この原理は私が考えたものではないということを
50 試験に出る XI
4B E0AA
2800
20
E044
4B E0AA
3000
E044
E028
E02C
E02F
E030
E031
E033
E036
E03A
B03D
E03E
E03F
E044 09
E045 44
E046 4D
E047 ED 79
E049 03
E04A 15
E042
E043
El
C9
E014 E5
E015 D5
E016 011FD0
E019 AF
E01A ED 79
E01C ED 4B E0AA
E020 213800
E023 3E 00
E025 CD E044
E010 CD E04E
E013 C9
0016
0017
0018
E000
E001
E002
E003
E004
E005
E009
E00A
E00B
E00C
E00D
EB
46
23
4E
23
ED 43 E0AA
56
23
5E
23
CD E014
最初に断っておく。
リスト 2-4, 2-5 を見ていただきたい0注意してみると分かるように,リスト 2-4 の前半
はリスト 2-2 とほとんど同じで ある。 違ってくるのは, E 04 E H の SETPCG からで ある。 ま
ずは ORDER というサブルーチンを呼んでいる。ここで何をやっているかというと,
青,赤,緑と8バイトずつのブロックになっているデータを,青の0段目,赤の0段目,
緑の〇段目,……という順序に並べ変えて , WORK ( E 0 AC „) から始まる24バイトに格
納しているので ある。 E 08 D „ 〜 E 0 A 3„ あたりの2重ループの作り方が実に微妙なので あ
る。特に注意すべきことは 「 LDI 」 を実行して BC レジスタが0になったかどうかの判断
を , 「JP PO , 〜」(パリティ•オッド)で判定している点で ある。 「 LDI 」 はゼロフラグを
変えないので ある。
リスト 2-4 3 倍速 PCG 定義の機械語部分
D 115 E D
E 2 D D 3 C
E 2 D 7 C
第 2 章 PCG 51
E04B
E04D
20 FA
C9
JR
RET
NZ,SET2
E09E
07
E091
E08D
K093
E096
E097
E099
E09A
E09B
E0A6 21 E0AC
E0A9 C9
E0AA
K0AC
E04E
CD
E086
E051
06
16
E053
0E
00
E055
16
17
E057
IE
18
E059
3E
08
E05B
08
E05C
D9
E05D
F3
E05E
01
1A01
E061
ED
78
K063
F2
E061
E066
ED
78
E068
FA
E066
E06B
D9
E06C
08
E06D
ED
A3
E06F
42
E070
ED
A3
E072
43
E073
ED
A3
E075
06
16
E077
08
E078
3E
0B
E07A
3D
E07B
C2
E07A
E07E
08
E07F
0C
E080
3D
E081
C2 E06D
E084
FB
E085
C9
E086
D9
E087
06
08
E089
D9
E08A
11
E0AC
E08D
E5
E08E
01
0003
E091
ED
A0
;Acc = ASCII
SETPCG :
CALL
ORDER
;CHANGE
ORDER
•
し D
B.BLUE
LD
C t 00H
LD
D t RED
;RED
LD
E f GREEN
;GREEN
LD
A f 08H
;COUNTER
EX
AF f AF f
•
EXX
t
DI
LD
BC,1A01H
VDSP0 :
IN
A f (C)
JP
P,VDSP0
VDSP1 :
IN
A f (C)
#
jp
M f VDSP1
t
EXX
•
EX
AF.AF*
; A f =COUNTER
SETP :
OUTI
16,OUT
BLUE
し D
B f D
4
OUTI
16 f OUT
RED
LD
B,E
4
OUTI
16,OUT
GREEN
; 16+4+16.4+16:
•
56
•
LD
B.BLUE ;
;7
;7 = 7
t
EX
LD
AF t AF*
4
A.0BH
7
DLY :
DEC
A
4
JP
EX
NZ.DLY
10
AF,AF»
4
;4 + 7M4 + 10”l 1+4 = 169
#
i
INC
C
4
DEC
A
4
JP
NZ.SETP
10
;4+4+10=18
;56+7+169+18:250
El
RET
CHANGE ORDER
B0 t B1 f ... f B7 f R0 f R1 f ••• f R7 f G0 f G1 f ••• f G7
- >B0 f R0 f C0 f B1 f R1 f Gl f .•• f B7 f R7 f G7
B,8
: COUNTER
ORDER : EXX
LD
EXX
LD
ORDER0 : PUSH
LD
ORDER 1 : LDI
; (DEX-(HL) f INC DE f INC HL t DEC BC
DE f WORK ;BUFFER
HL
BC f 3
JP
LD
LD
ADD
LD
JP
PO.ORDER2
A,C ;SAVE C
C f 7
HL f BC ;HL=HL+7
C f A ;BACK C
ORDER1
3 BYTES MOVED?
ORDER2 :
POP
INC
EXX
DEC
EXX
JP
HL
HL
B
: DEC COUNTER
NZ.ORDER0
LD
RET
HL f WORK ;NEW PCG DATA
BCWORK : DS
WORK : DS
END
2
24
2 9 E 9 F 3
E 7 0 0 4 c
13 9 5 9 2
E 2 D 0 D c
E F 0 12 3
9 9 A A A A
0 0 0 0 0 0
E E E E E E
試験に出る
リスト 2-5 3 倍速 PCG 定義
00 CLEAR &HE000
10 MEM$(&HE000,16)=HEXCHR$(
20 MEM$(&HE010 f 16)=HEXCHH$(
30 MEM$(&HE020,16)=HEXCHR$(
40 MEM$(&HE030 f 16)=HEXCHR$(
50 MEM$(&HE040,16)=HEXCHR$(
60 MEM$(&HE050 f 16)=HEXCHR$(
70 MEM$(&HE060,16)=HEXCHR$(
80 MEM$(&HE070,16)=HEXCHH$(
90 MEM$(&HE08O,16)=HEXCHR$(
200 MEM$(&HE090 f 16)=HEXCHH$(
210 MEMS(&HE0A0,16)=HEXCHR$(
220 DEFUSR0=&HECOO
230 »
240 CGEN 1 : LOCATE 0,0
250 FORI=0TO255:PRINT #0,CHR$(I) ; : NEXT:PRINT
260 CGEN 0
270 »
280 TIME=0
290 FORI=0TO255
300 A$=USR0(CHR$(&H7 I &HD0,48,I)+STRING$(24,1))
310 NEXT
320 PRINT TIME
このよ一にして並べ変えたデータを E 06 D „ から OUTI を使って,走査線1本当たり,
青,赤,緑の3バイトずつ PCG にセットしているわけである。ここでの注意点は , OUTI
命令のひねくれ方である。実にムツとすることに, OUTI は, B レジスタを一つ減少さ
せてから, OUT 動作を行なうのである。よって,1500„番地に OUT したいならば, BC を
1600„にしておかなければならないのである。むむむ一ん。あと特筆すべきことは,その3
バイトを OUT する期間である。どうやら60クロックぐらいの間に済まさなければならな
いよ一である。しかし,私はその根拠は計算できない。ま,56クロックで収まっているの
だからよしとしてしまうのである。
この3倍速 PCG 定義を使うと,256個の PCG 定義が4秒強で済むことになる。しかし
この世にその筋として生を受けたからには,「もっとオイシイ手はないかかかっ丨」と考え
なければならん。そして思い付いためが,24倍速 PCG 定義である。一体ど一やってやるの
かというと,原理は単純で,
PCG 定義で大事な「表示されない VRAM」 の数(行数)を增やしてしまおう。
という,実にその筋的な発想なのである。第1章で CRTC をやったが, CRTC の第6レジ
スタ ( R 6) は「垂直表示文字数」であった。普段はここは25なのだが,7減らして18に
してしまうと,ど一だ「表示されない VRAM 」 がどっと増えただろ一が。7行増えたのだ
から,3倍速 X 8倍速で24倍速である。機械語部分が リスト 2-6, BASIC から使ってい
るのが リスト 2-7 である。リスト 2-6 でやっているのは, CRTC をいじっているほか
は,リスト 2-4 の3倍速 PCG 定義と大差ない。そこでさっさとリスト 2-7 の説明に行って
しまうのである。
リスト 2-6 24倍速 PCG 定義の機械两部分
•
.Z80
.PHASE
0E000H
0016
BLUE
EQU
15H+1
0017
RED
EQU
16H+1
0018
GREEN
EQU
17H+1
001D612C330
EEDC 8040020
4A8BD1 38110
1A27C0A00E0
DB0193D0500
C40DCFEEEE0
3D10A98A010
2E23FD07E90
E9000892C30
57E020DCAC0
3DA1580D1F0
2EA210E3140
6FB03E6B999
5A4E0360D0C
0FDA98AE870
E1EA71F300E
A00BDE886EC
ADE4E17000A
314DD7D6991
404E41E1D72
D5D 04606900
EDCE41E0CEE
35049013 BED
2E 04006 AF98
E9ED9E2D022
4C3CC0FEEEC
30801683 D09
2E32E1746AD
6E0EO6D32D5
4403E0EACE0
BD1540ADD09
EC2D4E1E30D
第2阜 PCG 53
E07A 0616
E07C 0E 00
E07E 1617
E080 IE 18
E082 3E 40
E084 08
E085 D9
E086 F3
E087 011A01
E08A ED 78
E049
E04C
E04E
B050
E051
E053
E055
E056
E059
E05A
E05C
E05D
E060
B063
E064
E067
E068
E069
E06A
B06B
E06C
0135A0
57
IE 08
C5
21 0030
CD E070
Cl
21 0050
09
44
4D
14
ID
C2 E05C
E06F
C9
E000
E003
E005
E007
E008
E00A
01 1800
3E 06
ED 79
03
3E 12
ED 79
E00C
E00F
E010
011FD0
AF
ED 79
E012
E015
E018
E01A
013DA0
2A 0260
16 00
CD E070
E01D
E020
E023
E025
0125A0
21 0260
16 20
CD E070
E028
E02B
E02E
E02F
E030
E033
E036
E039
E03C
E03F
EO40
E043
E044
E046
21 E200
22 E0AF
AF
F5
CD E056
2A E0AF
CD E07A
2A K0AF
01 00C0
09
22 E0AF
FI
C6 08
C2 E02F
START
LD
LD
OUT
INC
LD
OUT
LD
XOR
OUT
BC f 1800H ;SET CRTC
A,6
(C) f A
BC
A,18 ;DISP JUST 18 LINES
(C) f A
BC f 1FD0H
A
(C) f A
;FOR turbo
LD
LD
LD
CALL
BC f 3800H^5A0H ;KANJI VRAM
HL t 260H ;COUNTER
D f 00H
SETIO
LD
LD
LD
CALL
LD
LD
LOOP :
XOR
PUSH
CALL
LD
CALL
LD
LD
ADD
LD
POP
ADD
jp
LD
LD
OUT
INC
LD
OUT
RET
BC f 2000H^5A0H ;ATTRIBUTE
HL f 260H ;COUNTER
D f 20H
SETIO
HL.0E200H ;DATA AREA
(HLWORK) f HL ;SAVE ADDRESS
A ;TOP OF ASCII CODE
A
AF
SET8
HL,(HLWORK>
SETPCG
HL f (HLWORK)
BC , 24 拿 8
HL 9 BC
(HLWORK),HL
AF
A f 8
NZ •し OOP
;DATA ADDRESS
;NEW ADDRESS
;CHECK COUNTER
BC,1800H
A,6
(C) f A
BC
A,25 ;CRTC WO MODOSU
(C) f A
SET8 :
SET80
LD
LD
LD
PUSH
LD
CALL
POP
LD
ADD
LD
LD
INC
DEC
JP
BC f 3000H-f5A0H
D t A ;ASCI I CODE
B 9 8 ;COUNTER
BC
HL,48
SETIO
BC
HL f 80
HL f BC
B f H
C f L ; BC=NEXT ADDRESS
D ;INC ASCII CODE
E ;DEC COUNTER
NZ f SBT80
RET
SETIO :
OUT
INC
DEC
LD
OR
JP
RET
(C) f D
BC
HL
A f H
L
NZ.SETIO
; Acc=ASCII
SETPCG : LD
B f BLUE
LD
C t O0H
LD
D f RED ;RBD
LD
E,GREEN ;GREEN
LD
A f 08Ht8 ; COUNTER,8 CHARS!
EX
AF t AF f
EXX
•
DI
LD
BC f 1A01H
VDSPO : IN
A f (C)
D 3 B c 5 2 9
E 0 2 7 B c c
0 2 3 4 5 6 9
7 7 7 7 7 7 7
0 0 0 0 0 0 0
E E E E E E E
0
0
8 6 9 9 9
10 7 17
1 E D 3 E D 9
0 3 E 0 3 E c
試験に出る XI
E08C
E08F
E091
F2 E08A
ED 78
FA E08F
JP
VDSP1 : IN
JP
P f VDSP0
A f (C)
M f VDSPl
E094
D9
EXX
E095
08
#
EX
AF f AF 1
; A f =COUNTER
E096
ED
A3
SETP :
OUT I
; 16,OUT
BLUE
E098
42
LD
B.D
;4
E099
ED
A3
OUT I
; 16 f OUT
RED
E09B
43
LD
B,E
;4
E09C
ED
A3
OUT I
; 16, OUT
GREEN
;16+4+16.4.16
•
= 56
E09E
06
16
§
LD
;7
;7 = 7
E0A0
08
t
EX
LD
AF,AF*
;4
E0A1
3E
0B
A.0BH
;7
E0A3
3D
DLY :
DEC
A
;4
E0A4
C2
E0A3
JP
EX
NZ t DLY
;10
E0A7
08
AF.AF*
;4
E0A8
E0A9
E0AA
E0AD
E0AE
E0AF
0C
3D
C2 E096
FB
C9
;4+7+<4+10> 拿 11+4:169
INC
DEC
JP
; 4f4+10=18
;56+7+169+18=250
El
RET
%
HLWORK : DS
END
C
A
NZ.SETP
4
4
10
リスト 2-7 24 倍速 PCG 定義
100
CLEAR &HE000
110
MEMS(&HE000 f 16)=HEXCHR$(
•01
00
18
3E
06
ED
79
03
3E
12
ED
79
01
D0
IF
AF">
120
MEM$(&HE0 10,16) =HBXCHR$(
•ED
79
01
A0
3D
21
60
02
16
00
CD
70
E0
01
A0
25 M )
130
MEM$(AHE020 f 16)=HEXCHR$(
•21
60
02
16
20
CD
70
E0
21
00
B2
22
AF
E0
AF
F5">
140
MEM$(&HE030 f 16)=HEXCHR$(
•CD
56
E0
2A
AF
E0
CD
7A
E0
2A
AF
E0
01
C0
00
09" >
150
MEM$(&HEO40 9 16)=HEXCHR$(
•22
AF
E0
FI
C6
08
C2
2F
E0
01
00
18
3E
06
ED
79" >
160
MEM$(«tHE050 f 16)=HEXCHR$(
f 03
3E
19
ED
79
C9
01
A0
35
57
IE
08
C5
21
30
00 M )
170
MEM$(&HE060 f 16)=HEXCHR$(
•CD
70
E0
Cl
21
50
00
09
44
4D
14
ID
C2
5C
E0
C9 ff )
180
MEM$(&HE070 f 16)=HEXCHR$(
•ED
51
03
2B
7C
B5
C2
70
E0
C9
06
16
0E
00
16
17” >
190
MEM$(&HE080 f 16)=HEXCHH$(
•IE
18
3E
40
08
D9
F3
01
01
1A
ED
78
F2
8A
E0
ED ff )
200
MEMS(&HE090 f 16)=HEXCHR$(
•78
FA
8F
E0
D9
08
ED
A3
42
ED
A3
43
ED
A3
06
16" >
210
MEM$(&HE0A0 f 16)=HEXCHR$( M 08
3E
0B
3D
C2
A3
E0
08
0C
3D
C2
96
E0
FB
C9
00 tf )
220
i
230
WIDTH 80
240
CGEN 1
250
FOR 1=0 TO 255:PRINT «0
CHR$( i y
; : NEXT:PRINT
260
CGEN 0
270
FOR 1=0 TO 255
280
MEM$(&HE200+I 拿 24,24 >=STRING$(24•I>
290
NEXT
300
TIME=0
310
FOR 1=0 TO 10:CALL &HE000:NEXT
320
PRINT TIME
リスト 2-7 では最初に WIDTH を 80 にしている。そ一なのである0リスト 2-6 は簡単に
するために , WIDTH 80 でしか動かないよ一になっているのだ。しかも PCG 用のデータ
は,あらかじめ青,赤,緑,青,赤,緑,……というように並べ換えられて, E 200 H から
6144 (1800 H ) バイトに格納されていることになっている。 270 〜 290 行で,そのダミーのデ
一夕を作っているわけである。実際の PCG 定義は 「CALL & HE 000 J 一発で OK であ
る。速すぎるので 10 回実行している。結果は, 256 個の定義にかかる時間は約 0.6 秒と出
た。さて,理論的には全両面を表示されない VRAM (?) にして 26X 3 =78 倍速なんて
いうのができそうだが,ちょっと無理のようである。実は 16X 3 =48 倍速までやってみた
第 2 章 PCG 55
のだが,ソフトウェアでタイミングをとる悲しさで,所々で PCG の定義に失敗してしまう
のだ。それで安全のために24倍速でとどめておいたのである(その筋な某ユーザーは,も
う一工夫して,うまくソフトウヱアでタイミングをとり,48倍速定義を成功させたそうで
ある0ももも )0
CG 勿読み出し
話は変わって, BASIC の CGPAT $ 関数に対応する部分である。 リスト 2-8, 2-9 に ROM
CG を読み出すプログラムを示す。リスト 2-2 〜7を参考にすれば, PCG から読み出すこと
などは簡単であろうと,勝手に判断してしまうのである。 達者で暮らしていただきた
い, と言いつつ何の説明もせずに次に進んでしまうのである。
リスト 2-8 ROM CG 読み出しの櫬械語部分
.Z80
•
.PHASE
0E000H
E000
EB
i
EX
DE f HL
K0O1
46
LD
B.(HL) : HI
E002
23
INC
HL
E003
4E
LD
C f (HL) ;LOW
E004
23
INC
HL
E005
ED 43 E077
LD
(BCWORK) f BC
E009
56
LD
D p (HL) : COUNT
E00A
23
INC
HL
E00B
5E
LD
E t (HL) : ASCI I
CODE
E00C
23
INC
HL
E00D
CD E017
•
CALL
SET0
E01O
011400
•
LD
BC t 1400H
E013
CD E051
CALL
READCG
E016
C9
•
RET
E017
E5
SET0 :
PUSH
HL ;SAVE
POINTER
E018
D5
PUSH
DE : SAVE
COUNT and ASCII CO
DE
E019
01 1FD0
LD
BC,1FD0H
;FOR turbo
E01C
AF
XOR
A
E01D
ED 79
•
OUT
(C),A
E01F
ED 4B E077
LD
BC,(BCWORK)
E023
21 3800
LD
H し, 3800H
;KANJI
VRAM(turb
〇 )
E026
3E 00
LD
A f 00H
E028
CD E047
•
CALL
SET1
E02B
ED 4B E077
f
LD
BC,(BCWORK)
E02F
212800
LD
HL 9 2800H
: ATTRIBUTE
E032
D1
POP
DH
E033
D5
PUSH
DE
E034
3E 00
LD
A f 00H
: ROM CG # COLOR=0
E036
CD E047
•
CALL
SETl
E039
ED 4B E077
t
LD
BC,(BCWORK)
E03D
213000
LD
HL 9 3000H
: VRAM
E040
D1
POP
DE
E04 1
7B
LD
a 9 e
;ASCII
CODE
E042
CD E047
•
CALL
SETl
E045
El
•
POP
HL
E046
C9
•
RET
E047
09
SET1 :
ADD
HL.BC
E048
44
LD
B f H
E049
4D
LD
C f L : BC=HLfBC
E04A
ED 79
SET2 :
OUT
(C) f A
E04C
03
INC
BC ;INC ADDRESS
E04D
15
DEC
D ;DEC COUNTER
56 試験に出る XI
E04E
E050
E051
E053
E054
E055
E058
F05A
E05D
E05F
E062
E063
E065
E066
E067
20 FA
C9
IE 08
D9
F3
011A01
ED 78
F2 E058
ED 78
FA E05D
D9
ED 78
77
23
03
JR
RET
READCG : LD
EXX
NZ f SET 2
E f 08H ;COUNTER
VDISP0:
VD1SP1 :
DI
LD
IN
JP
IN
JP
SETP :
E068
E069
E06A
E06B
E06D
E06E
E071
E072
23
2B
EXX
P : IN
LD
INC
INC
12+6+6=31
NOP
INC
DEC
16
BC,1A01H
A, (C)
P f VDISP0
A,(C>
M,VDISP1
A, (C)
(HL) f A
HL
BC
12 t READ 1 BYTE
7 f STORE DATA
6 f INC POINTER
6,INC I/O ADDRESS
HL
HL
3E 0D
3D
C2 E06D
ID
C2 E063
4+6 + 6 =
DLY :
6, DUMMY
LD
DEC
JP
DEC
JP
A f 0DH
A
NZ t DLY
E
NZ f SETP
E075
E076
E077
FB
C9
7^(4+10)t13+4+10=203
31+16+203=250
El
RET
BCWORK : DS
END
ROM CG « み出
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
CLEAR &HE000
MEM$(&HE000 f 16)
16)
MEM$(&HE020 f 16)
MEM$(&HE030 f 16)
MEM$
MEM$.
MEM$(&HE060 f 16)
MEM$(&HE070 f 16)
DEFUSH0=&HEO00
=HEXCHR$(
=HEXCHR$(
=HEXCHR$(
=HEXCHR$(
HEXCHRS
HEXCHRSi
=HEXCHR$(
=HEXCHR$(
EB
01
4B
00
Dl
C9
5D
E0
46 23
00 14
77 E0
28 Dl
7B CD
IE 08
E0 D9
ID C2
4E 23
CD 51
21 00
D5 3E
47 E0
D9 F3
ED 78
63 E0
ED 43 77
E0 C9 E5
38 3E 00
00 CD 47
El C9 09
01 011A
77 23 03
FB C9 00
E0 56
D5 01
CD 47
E0 ED
44 4D
ED 78
00 23
00 00
23 5E 23
D0 IF AF
E0 ED 4B
4B 77 E0
ED 79 03
F2 58 E0
2B 3E 0D
00 00 00
CD 17 E0
ED 79 ED
77 E0 21
21 00 30
15 20 FA
ED 78 FA
3D C2 6D
00 00 00
WIDTH80
C = 0
A$ = USR0(CHR$(&H7 f &HD0 f 48
A$=RIGHT$(A$ f 8)
PRINT #0 AS
PRINT #0 LEFTS(CGPAT$(C)
C)4STRING$(8 f atH30)
turbo におけ 3PCG/CG
さあて,話は変わって turbo である。ここまでの話からも分かるよ一に, XI の PCG は
強力無比と言えるのだが , PCG 定義, 読み出しの速度と手間は実にうっと一しい ので あ
る0伝え聞くところによると,まともにインター フェイ スなどを作ったら コストがか かり
すぎるので,あのよ一になったということだが,そのウワサの真偽はともかくとして,う
っと一しいということだけは真実なのである。シャープもその点に ついては 正しく理解し
ていたらしく, turbo では「高速アクセスモード」という機能が付けられて ぃる 。これ
第 2 章 PCG 57
は, CG アクセスの下準備を VRAM , 漢字 VRAM , アトリビュートに各1バイト,計3バ
イトを書き込むだけで済むようにしたうえに,垂直帰線期間だけでなく,水平帰線期間に
もアクセス可能にしたものである。つまり,走査線1本ごとにアクセスできるわけであ
る。しかもうれしいことにソフトウェアでタイミングを取る必要もないのである。ど一し
てかというと, turbo がハード的に,勝手にタイミングを取ってくれるのだ 0 すなわち , PCG
にデータをセットしようとして, CPU が OUT 命令を実行したとすると,その瞬間にウェ
イトがかけられてタイミングが取れるのである。ウェイトとは平たく言えば「金縛り」み
たいなもので, CPU は気絶させられるわけである。で,周りの回路が準備 0 K になったと
ころで CPU に「活」を入れる 0 CPU は何も気付かずに OUT 命令を完了して,また 4 MHz
のステップを踏み続けるのである 0
turbo ではこの 高速 アクセスモードにより,256個の PCG を, 低解像度 モード (200 ライ
ン)のとき約 0.5 秒, 高解像度 モード (400 ライン)のとき約0.27秒に短縮できたのであ
る。さもなくば SYMBOL 文などは 大ひんしゆくであったろう。 めでたしめでたし。
まずは実物を見ていただきたい0 リスト 2-10, 2-11 である0リスト 2-10 はこの章のア
リスト 2-10 turbo 用 CG R/W ブログラムの機械語部分
58 試験に出る XI
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
580
590
CLEAR &HE000
MEM$(4HE000 t 16)=HEXCHR$( #t EB 01 D0 20 BD A3 01 FF 40 ED A3 01 FF 28 ED A3"
MEM$(&HE010 f 16)=HEXCHR$( M 01 FF 38 ED A3 56 23 5E 23 46 23 0E 00 7E 23 B7”
MBM$(AHE020 f 16)=HEXCHR$( ft C2 2E E0 04 ED A3 79 83 4F 15 C2 23 E0 C9 BD A2"
MEM$(&HE030 f 16)=HEXCHR$( ## 04 79 83 4F 15 C2 2E E0 C9 00 00 00 00 00 00 00 M
DEFUSR0=AHE000
i
WIDTH 40
,1 2 3 4 5 6 7 8
*1FD0.KANJI,ATT,VRAM,COUNT(16/8),STEP(2/1),1/0 PORT HIGH , R/W
, 8*8 の ROM CG を! * む(アルファペット〉
A$ = USR0(CHR$(&H23 f 0 f 0 f 66 f 8 f 2 f &H14 f 1)♦STRINGS ( 48 f 0 ) ) : L=8 : GOSUB ,f DUMP f#
•8*16 の ROM CG を « む(アルファベット〉
A$ = USR0( CHR$ (&H63 9 0 9 0 9 66 9 16 f 1 f &H14 f 1)^STRINGS ( 48 9 0 ) ) : L=16 : GOSUB f, DUMP M
, 8*16 の ROM CG を « む(澳字: r 筋 j の左側〉
A$ = USR0(CHR$(&H63 f AH 86 t 0 f &HDA f 16 f 1 f AH14 t 1)♦STRINGS(48,0)) : L=16 : GOSUB M DUMP
SUJI$=A$
§
GOSUB"ALL"
t
’PCG をノーマルモードでセット
A$=USR0(CHR$(&H23 f 0 f &H20 f 0 f 8 f 2 f &H15 f 0)4STRING$(8 f &H3))
A$=USR0(CHR$(&H23 f 0 f 4H20 f 0 f 8 f 2 f &H16 f 0)^STRING$(8 f &HC))
A$=USH0(CHR$(&H23 t 0 f &H20 f 0 f 8 f 2 f atH17 f 0)^STRING$(8 f &H30))
PCG を外字モードでセット
A$=USR0(CHR$(AH23 f atH10 f &H20 f 4 I 16
A$=USR0(CHR$(&H23 f &H10 f AH20 f 4 f 16
A$ = USR0(CHR$(&H23 f &H10 f AH20 f 4 f 16
, & H15 f 0)^SUJI$)
, & H16 f 0)^SUJI$)
H17 f 0)^SUJI$)
OUT &H3lA4 f AH4
OUT &H39A4 f &H10
OUT &H21A4 9 &H 27
END
i
LABEL M DUMP M
A$=MID$(A$ f 9 f L)
FOR 1=1 TO L
B=ASC(MID$(A$ f I
NEXT:PRINT
Q$=INKEY$(1)
RETURN
:•左筋を表示
: B$ = RIGHT$( M 0000000 ff 4BIN$(B) f 8) : PRINTBS
LABBL if ALL tf
CLS:KMODE 0
CGEN 1 : LOCATE 0 f 0
FOR 1=0 TO 255:PRINT #0 t CHR$(
CGEN 0 : KMODE 1
RETURN
); : NEXT
センブラで書かれたプログラムの中では一番短いものだが,なんと tur b 0 の PCG,ROM
CG , 漢字 ROM の読み書きすベてに対応してしまつているのだ(多少はナニだけどね、リ
スト 2-10 の中のループの£028„番地と E 033 H 番地で C レジスタを変化させているが,こ
れはちゃんと意味があつてやつている。使い方はリスト 2-11 の180,190行を見ていただ
きたい0パラメータは順に,
•1 FD 0 H へのデータ
• 漢字 VRAM へのデータ
♦アトリビュートへのデータ
• VRAM へのデータ
第2章 PCG 59
❿ COUNT (8 X 8 を読むか8 x 16を読むか)
• STEP (8 x 8なら2, 8 X 16 なら 1)
• I / O ポートの上位アドレス (14 h 〜17 h )
籲 R / W のフラグ(読む=1/書く = 0)
となっている。
210行からは,まず8 x 8の ROM CG の読み出しである。 ASCII コードは66= 、、 B " で
ある。第1パラメータが 23 H で,図 2-3 を見るとビット6 = 0,ビット5 =1である。すな
わち8ラスタ CG アクセスで,高速アクセスである。おっと,ビット5の説明では 「 PCG 」
となっている。愛敬愛敬。さて,第6パラメータが2になっているが,なぜそのようにな
っているかというと, 8 X 8 の 「 BJ のパターンは,表示されるときは
7Ch» 42h* .
となっているのだが,読み出すと
7Ch , 7Ch , 42h , 42h , .
と 2 度ずつ繰り返してしまうのだ。だから 「 BC 二 BC +2」 としているのだ。230行からは
ビット6=1となり,8 X 16 の CG に対するアクセスである。このビット6により,アク
セスする ROM が変わるのである(表示される CG は変わらない)。250行からの漢字 ROM
の読み出しも同じようなものである。
次に310行から2度 PCG をセットしている。 turbo での PCG には,8 X 8として扱わ
れる ノーマル モードと,8 X 16 として扱われる外字モードの二つのモードがある0外字モ
ードの場合は偶数番目と,その次の奇数番目の PCG 2個が1個の8 X 16 の文字として扱
われる(たとえば0と1,2と3などの組)。よって, 16 X 16 の漢字は4個の PCG を合体
させて作ることができるわけである。256 + 4 = 64で, turbo は64個の漢字の外字を持てる
図 2-3 IFDOh = 画面管理 ボートの 意味
データ 内容
コントロール
ビット0
0 =低 解像度 モニタ (200 ライン)
1テ*; 難度 モこ夕(400ライン ) t —
ビット1
0=1本ラスタ/ドット
1=2本ラスタ/ドット
ビット2
0= ノーマル ( 8ラスタ/ CHAR 〉(25 行,20行)
1=漢字 (16 ラスタ/ CHAR )(12 行,10行)
ビット3
0=バンク0 表示
1=バンク1 表示
ビット4
〇=バンク〇アクセス
1=バンク1アクセス
ビット5
0 = PCG コンパチアクセス
1 = PCG 高速 アクセス
ビット6
0=8ラスタ CG アクセス
1 = 16ラスタ CG アクセス
ビット7
〇=アンダーラインなし
1=アンダーラインあり
60 試験に出る XI
ことになる。410行からは「筋」の左半分を表示している。漢字 VRAM のビット4が立っ
ていて,外字モードになっている点に注意。これにより PCG の4番と5番が上下になって
同時に表示されるわけである。
以上が PCG なわけであった。 XI では PCG を使うことにより ALL BASIC でも,まと
もに遊べるゲームができてしまうのである。 マシン 語にすればもっと遊べるのである。と
いうわけで, PCG はゲーム街道をお通りなのであった
第2章 PCG 61
漢字名野出亜留
第 3 章
漢字名野出 S 留
第2章では PCG をやったのである。となれば,この章では漢字ということになるわけだ。
漢字:)ード勿基本
大体の人は知っているよ一に,漢字にも ASCII コードなどと同じように,「漢字コード」
なるものがあり,整理整傾に一役買っているのである。そいでもって,この漢字コードと
いうやつは実に食わせものなのだ。まず,恐ろしいことに,この漢字コードには3種類が
群雄割拠しているのである。
① JIS 漢字 コード
② 区点コード
③ シフト JIS 漢字 コード
である。これらは三つとも「2バイトコード J , つまり,2バイトで漢字1文字を表現する
コードである。
①まず, JIS 漢字コードの場合は,
上位バイト (1 バイト目)は21„〜 7 E „
下位バイト (2 バイト目)も21„〜 7 E h •-
となっている。ちなみに「鲭 J の JIS コードは 3 B 2 A H である。
さて,それぞれのバイトで,21„〜 7 E H しか使っていないことからも分かるように,この
コードには「隙間」ができている。たとえば,000 0 H 〜 2120 H が空いてるし, 217 F H 〜2220„
なども空いているのである0なんでこうなっているかというと,どうやらコントロールコ
ー ドを入れたくなかったからのようである。つまり, ASCII コードでは 00 H 〜 20 H は (20 H の
スペースは違うけど)コントロールコードとして特殊な機能を割り当てられているから,
避けたようなのである。また,それ以外にも空きがある。たとえば, 2577 H 〜257 E H などで
ある。この部分はカタカナとギリシャ文字の隙間なのである0
そいでもって, JIS 漢字コードは第1水準と第2水準に分かれるわけであるが,
第1水準 = 2121 h 〜 4 F 53 h
第2水準 = 5020 h 〜7424„
となっている。第1水準の 4 F 54 H 〜4 F 7 E H と,第2水準の 7425 H 〜7 E 7 E H は未定義(空き)
である。
なぜ第1,第2水準に分けられているかというと,これは使用頻度によるわけだ。たと
えば第2水準には國(国),學(学)などの旧字体や,瑟齎靉 蠡靨豫 鼈などの,見たことも
聞いたこともないよ一な漢字が並んでいるわけである。それはともかく,一言注意してお
かなければならないのは,第1水準が(記号は別として)「読み」ごとに分類されているの
64 试験に出る XI
に対して,第2水準は,部首(偏や冠など)ごとに分類されているということである。第
2水準の漢字には,読み方も分からないようなものが多いから,妥当な気もするが,読み
方も分からないよ一な漢字をどう使うのであろうか。 ま,ど一でもいいけどね。
② 次に区点コードである。
区点コードは JIS コードを少しアレンジしただけのものである。すなわち, JIS の上
位,下位それぞれから20„を引いて,10進数で表し,もう1回くっっけ直したものであ
る。だから,たとえば JIS コードの 4 B 7 A „ (繭)は,
4 B „-20 h = 2 B „ = 43
7 Ah 一 20 h = 5 Ah = 90
ということになり,区点コードは「4390」となるのである。はっきり言うが,これは4桁
の10進数ではなく,「2桁の10進数が二つ」なのである。
この区点コードというやつは,ただ単に入力する際に A 〜 F を押さなくて済むというぐ
らいの意味しかない。これはまだ音訓変換さえもなかったような大昔に,漢字の入力方法と
して考え出されたものらしい。昔はコンピュータで漢字を使うのは大苦労だったのであ
る。
③ シフト JIS 漢字コード,
このシフト JIS というものは, JIS コードの短所を補おうとしてできたものである(結果
的には補えたのかど 一 だか知らない)。
たとえば JIS コードの4141„ (疏)を,普通の方法でブリントしようとすると,41„は
ASCII コードでは 「 AJ であるから,画面には 「 AA 」 と表示されることになる。そのよ 一
なことになっては, • ど一しよ一もないので, JIS コードを使う場合にはどうしても「漢字
IN / OUT 」 という,コントロールコードが必要になってくる。つまり,この場合だと,
(漢字 IN ), 41„,41„,(漢字 OUT )
の6バイトのデータで「疏」1文字を表現することになる。
それでは不便だということでできたのがシフト JIS コードである。こいつは,「第1バイ
卜が 81 h 〜 9F h もしくは E0„ 〜 EF„ で,なおかつ,第 2 バイトが 40„ 〜 7E„ もしくは 80„
〜 FC„ の 4 桁の 16 進数を漢字とみなす」というものである。ダサイことに第 1 バイトの範
囲に隙間がある。これは,半角のカタカナの ASCII コード A0„ 〜 DF„ だからなのであ
る0シフト JIS を考え出した人は,半角のカタカナと共存させたかったようである。もっ
とも,カタカナの代わりにグラフィックキャラクタの一部が使えなくなる。しかし,普通
の文字(半角のアルファベットなど)と漢字をほとんど同じように扱えるというメリット
が出てくるわけである。
ちなみに先程の「疏 J は,シフト JIS コードだと,
9160„
となり,「91„,60„」の2バイトのデータだけで「疏」を表現できることになる。第1バイ
卜が91,,であることが,漢字 IN の代わりになり,第2バイトの次に暗黙の漢字 OUT があ
るわけだ。つまり,これによって「漢字 IN / OUT 」 が不要になる。
そこでこの三つにコードの間の変換プログラムが必要となってしまうわけだ。というと
第3章漢 字65
ころで,
リスト 3-1 : JIS ー シフト
リスト 3-2 : JIS —区点
の変換プログラムとなっている。
リスト 3-1 JIS ^ シフ MIS
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
580
DEFSNG J
FOR J = &H8100 TO &H9FFF : GOSUB150 : NEXT : ’ すべての漢字を走る
FOR J=&HE000 TO &HEB00 : GOSUB 150: NEXT
END
LOCATE0,0 : PRINTCHRS(J) : P$=SCRN$(0,0,2}:
JI$=JIS$(P$) : GOSUB 260 :
IF EC THEN STOP
IF SJ$OHEX$(ASC(P$) ) THEN STOP :
9
SJ$=HEX$(ASC(P$)) : GOSUB 420 :
IF EC THEN STOP
IF JI$OJIS$(P$) THEN STOP :
RETURN
9
f JIS->SHIFT JIS
EC = 0
W$=MKI$(VAL(> >
JI1=ASC(RIGHT$(W$,1)) : JI2=ASC(LEFT$(WS f 1))
t
IF (JI1<&H21) OR (&H7E<JI1)THEN EC=1:RETURN
IF (JI2<&H21) OR (&H7E<JI2) THEN EC=1 -.RETURN
SJ1=INT((JI1-&H21)/2)+&H81
IF JI1>=&H5F THEN SJ 1=SJ 1-f (&HE0-&H9F-1)
一度表示してから
変換し
チェックする
変換し
チェックする
IF JI1 AND 1 THEN SJ2=&H40 : GOTO 360
IF (&H60<=JI2) THEN SJ2=SJ2+1
SJ2=SJ2+JI2-&H21
SJ = SJl>256-fSJ2 : SJ$ = HEX$(SJ)
RETURN
ELSE SJ2=&H9F:GOTO 370
,SHIFT JIS->JIS
EC = 0
W $= MKI $( VAL (>
SJl = ASC ( RIGHT $( W $ f 1))
SJ2=ASC(LEFT$(W$
IF (&H81<=SJ1)AND (SJ1<=&H9F)
IF (&HE0 く =SJ1> AND (SJ1<=&HEF)
EC=1:RETURN
JI1 = INT( (SJ1-&H81 )*2)*f&H21
THEN 490
THEN SJl=SJl-&HE0+&H9F-f 1:GOTO 490
IF (&H40<=SJ2) AND (SJ2<=&H7E) THEN 540
IF (&H80<=SJ2) AND (SJ2<=&HFC) THEN SJ2=SJ2-1:GOTO 540
EC=1:RETURN
IF SJ2>=&H9E THEN J11=J11 + 1 : SJ2 = SJ2-&H9E+&H40
JI2=SJ2-&H40+&H21
#
JI$=HEX$(JI1)+HEX$(JI2)
RETURN
リスト 3-1 は, JI $ に JIS コードを入れ , GOSUB 260とすると, SJ $ にシフト JIS コー
ドが入って返ってくる。その逆が GOSUB 420である。ただし,どちらの場合でも , EC =
1でリターンしたなら,あり得ないコードを変換しようとしたということである(つまり
エラー)〇
66 試験に出る XI
リスト 3-2 JIS 一区点
100 DEFSNG J
110 FOR J=&H8100 TO &H9FFF : GOSUB 150: NEXT
120 FOR J=&HE000 TO &HEB00 : GOSUB150:NEXT
130 END
140 1
150 LOCATE0 f 0:PRINT CHR$(J) : P$=SCRN$(0,0,2)
160 JI$=JIS$(P$) : GOSUB 240
170 IF KTSOKTN$(P$) THEN STOP
180 f
190 KT$=KTN$(P$) : GOSUB 320
200 IF JI$OJIS$(P$) THEN STOP
210 RETURN
220 f
230 1 JIS->KUTEN
240 W$ = MKI$(VAL( ' , &H ,, + JI$))
250 JIl=ASC(RIGHT$(W$ f 1)) : JI2=ASC(LEFTS(W$ f 1))
260 KT1=JI1-&H20
270 KT2 = JI2-&H20: ,単にバイアスをかけるだけ
280 KT$ = RIGHT$(STR$( 1 0000 + KT 1 * 1 00 + KT2),4)
290 RETURN
300 1
310 f KUTEN->JIS
320 W=VA し ( KT$)
330 KT1=W ¥ 100 : KT2=W MOD 100
340 JIl=KTl*f&H20
350 JI2 = KT2+&H20: ’ 単に バイアスをかけるだけ
360 JI$=HEX$(JI1*256+JI2>
370 RETURN
リスト 3-2 は SJ $ でなく, KT $ (区点コード)になっただけである。
細かなブログラムの動きは, 図 3-1 の「コード相関図」を見て納得していただきたい
思うしだいである。
図 3-1 コード相閫図
® シフト JIS コードと JIS 漢字コートの閭係
mm . nn はそれそれシフト jis コートの第 1 • 第2ハイトを示す
C _ J は未使用領域
B シフト JIS コートと区点コートの間係
通 00 3 F
00
40
7E
9E
9F
PC FF
81
0101
0301
9F
0163
0363
0164 0194
0364 0394
0201
0401
0294
0494
6101 6163
6164 6194
6201 6294
E0
EF
FC
FF
6301 6363
9301 9363
6364 6394
9364 9394
6401 6494
9401 9494
nnU そ n それシフト JIS コートの . 识 2
] は未使用;^或
を示す
表示す3勿てあ3
Xl/turbo で漢字を表示するには,
① 漢字 VRAM を使う ( turbo )
② グラフィック画面に描く
の 2 とおりの方法があるわけだ。①の場合は, turbo の漢字 VRAM に適当な値をシユポ
ポボンと数バイト書き込むだけ —— などと思ったら大間違い。漢字 VRAM に書き込むベ
きデータ(漢字 ROM アドレスという)の計算が結構面倒なのである。
まず, JIS コードは 2 バイトであるから,すなわち 16 ビットなわけだ。しかし,よ一く
見ると,第1,第 2 バイトともに, 21 H (&BQ0 10000 1) 〜 7E H (&BQ1111110) の範囲であ
る。すなわち,どちらのバイトでも, 第7ビットが 0 なのだ。よって, JIS コードは実際の
ところ 7 x 2 =14 ビットで済んでしまうということになる 0 それに対して, turbo の漢字
ROM アドレスというのは, I/O マッブの漢字 VRAM の所を見てもらえば分かるが, 13 ビ
ット (8 + 5ビット)の値なのである。まだ1ビットの差が残っているが,これはいかな
るわけかというと, JIS コードの 2821 H 〜 2F7E H と, 7425„ 〜 7E7E H が空いているからなどの
理由によるのである(ここらへんのところは, JIS の改訂などがあるのでちよいと違う部分
もぁる )0
というわけで, 図 3-2 が JIS コードー漢字 ROM アドレス変換の方法を図示したも
の, リスト 3-3 が変換を実行するプログラムである。少し付け加えておくが,要するに,
漢字 ROM アドレスの下位8ビット (3000 H 〜 37 FF H の I / O 空間に OUT するやつ)は,単
68 試験に出る XI
純に決定するのだが,3800 „〜3 FFF „ の漢字 VRAM の方のデータは図 3-2 の下の表を見な
ければならないということである。注意深く見れば規則性が見えてくるであろう。
図 3-2 turbo の JIS コード ㈠ 漢字 R0 M アドレスの間係
•JIS 漢字コード
JH7 JH6 JH5 JH4 JH3 JH2 JH1 JH0 儿 7 儿 6 JL5 儿 4 儿 3 儿 2
表
• 澳字 ROM アドレス
RH7 RH6 RH5 RH4
RL7 RL6 RL5 RL4 RL3 RL2
I
ROM アドレスとは閲
係なし
第 1/ 第 2 水準
儿 1 儿〇
RL1 RL0
JIS 漢字 コ
aa
■
I 1
溪字 ROM ァ
ドレス
JH6
JH5
JH4
儿 6
- - 1
JL5
RH4
〇
n
ra
ra
a
o
o
El
El
JH3
〇
n
ra
n
o
o
o
El
ma
JH3
〇
n
0
n
n
o
o
O
o
H
〇
n
n
ra
n
o
o
n
o
JH3
〇
n
n
a
o
o
o
n
n
I
n
n
n
a
o
n
o
o
n
ra
ra
ra
i
^ — ^ i
o
i
0
i
JH3
n
ra
ra
a
ra
o
a
n
o
n
o
o
n
n
o
n
n
n
■
■
■
■
■
■
■
■
n
o
n
n
o
o
o
JH3
n
ra
n
n
ra
n
o
o
n
JH3
第
a
ra
n
n
n
n
o
n
o
Ujg
2
n
n
o
ra
n
n
o
n
n
水
n
n
ra
n
ra
n
n
o
o
JH3
n
n
ra
n
n
a
a
o
n
JH3
準
n
n
n
o
n
B
n
n
n
o
JH3
n
n
n
n
ra
ca
n
n
n
n
JH3
n
n
n
n
n
ca
n
a
a
o
JH3
JIS 漢字コード
I
2021 h -277Eh
!
3021 m ~3F7E m
4021 h ~4F7E h
'
5021m~5F7Eh
6021„~6F7E h
7021 h ~777E h
リスト 3-3 turbo 用 JIS« 漢字 ROM アドレス変換
100 DEFSNG J
110 FOR J=&H8100 TO &H9FFF:GOSUB 150:NEXT
120 FOR J=&HE000 TO &HEAFF:GOSUB 150:NEXT
130 END
140 1
150 LOCATE 0,0:PRINT CHR$(J) : J$ = SCRN$(0 f 0,2)
160 IF J$ = M -X- M THEN 290
170 JI$ = JIS$(J$) : GOSUB 320 : # JIS -> ROM
180 IF EC THEN STOP
190 IF RLOINP(&H3000) THEN STOP
200 IF RHO(INP(&H3800) AND &H1F) THEN STOP
210 OUT &H3804 f RH OR &H80
220 OUT &H3805 f RH OR &HC0
230 OUT &H3004 f RL:OUT &H3005,RL
第 3 章漢
字 69
240 f
250 RL=INP(&H3000)
260 RH=INP(&H3800) AND &H1F
270 JI$="":GOSUB 490 : , ROM -> JIS
280 IF JI$OJIS$( J$) THEN STOP
290 RETURN
300 1
310 1 JIS->ROM
320 EC=0
330 JI=VAL<"&H"+JI$>
340 RL=(JI AND &B11111) OR ((JI Y 8) AND &B11100000)
350 RW1=(JI ¥ &H1000) AND 7 : , JH6,JH5,JH4
360 RW2=(JI ¥ &H800) AND 1 : , JH3
370 RW3=(JI ¥ &H20) AND 3 : # JL6 f JL5
380 ON RW1 GOTO 390,400,450 , 450 , 450•450,410
390 EC=1 : RETURN
400 RH=&B0 OR RW2 : GOTO 420
410 RH=&B11100 OR RW2
420 IF RW3=2 THEN RH=RH OR 2
430 IF RW3=3 THEN RH=RH XOR 1
440 RETURN
450 RH=((RWl-3>*3+l+RW3> 本 2 OR RW2
460 RETURN
470 1
480 f ROM->JIS
490 EC=0
500 JI2 = RL AND &B11U1 : *RL4 - RL0
510 JI1=(RL ¥ &H20) AND &B111 : , RL7 - RL5
520 IF RH<4 THEN 580 : , 2121H • 277EH
530 IF RH>&H1C THEN 590 : , 7021H - 777EH
540 JI1=JI1 OR ( ( ( (RH ¥ 2 )-f 7 ) ¥3 ) 10 )
550 JI1=JI1 OR (RH AND 1>*8
560 JI2=JI2 OR (((((RH ¥ 2>♦1>MOD3}♦1}*&H20>
570 GOTO 650
580 JI1=JI1 OR &B1 00000 : GOTO 600
590 JI1=JI1 OR &B1 110000 :GOTO 600
600 RW=RH AND 3
610 IF RW=0 THEN JI2=JI2 OR &B1 00000 :GOTO 650
620 IF RW=2 THEN JI2=JI2 OR &B1 000000 :GOTO 650
630 IF RW=1 THEN JI2=JI2 OR &B1 100000 :GOTO 650
640 EC=1:RETURN
650 JI$ = HEX$( JI1)-fHEX$( JI2 ) : RETURN
210 〜 230 行のルーチンは変換を実行した後で,実際に漢字 VRAM へそのデータを
OUT するものである。図 3-3 にあるように,左側/右側の指定なども行なっていることに
注意である。
図 3-3 漢字 VRAM の各ビットの機能
70 試験に出る XI
さらに表示す 3 仍 T あ 3
②のグラフィックに表示する場合をやるのである。これは XI と turbo の場合に分かれ
るのであるが, turbo の場合は,第2章でやった 「CG (漢字 ROM ) の読み出し」を実行し
た後で,そのデータをグラフィックに書き込んでしまえばよいわけであるから,さっさと
XI の場合に行ってしまうわけである。
XI における漢字 ROM といえば , CZ - 8 KR , CZ -8 BK 2 である ( X 1 F / G の model 20に
は標準で内蔵している)。で,そいつのアクセス方法が主題になるわけだったりする。
漢字 ROM の読み出しは リス ト 3-4 である。これは JIS コードを入力して,対応する漢
字を画面の左上に表示するブログラムである。説明すると,
120〜140行: JIS コードを入力し,1バイト目 ( JI 1) と2バイト目 ( JI 2) に分離す
る。
150〜170行: ROM に JI 1と0を OUT し,2バイト読む。
リスト 3-4 XI 用漢字 ROM 読み出しプログラム
100 INIT:PALET 1 f 7 : CLS4
110 f
120 LOCATE 0,5:INPUT JIS : 1 INPUT JIS CODE
130 JI1=VAL<"&H"+LEFT$(JI$ , 2}> : *JIS HIGH
140 JI2 = VAL( M &H M + RIGHT$(JIS f 2)) : 1 JIS LOW
150 OUT &HE80,JI1
160 OUT &HE81 9 0
170 GOSUB 330 : , READ 2 BYTE FROM ROM
180 : , GET R1(FROM TABLE)
190 f
200 R=Rl*&H100+(JI2-&H20)*&H10
210 OUT &HE82,0
220 OUT &HE80,ASC(LEFTS(MKIS(R) f 1)): f SET LOW ADDR.
230 OUT &HE81,INT(R/256> : , SET HIGH ADDR.
240 FOR 1=0 TO15
250 GOSUB 330 : , READ 2 BYTE FROM ROM
260 LP=R1 : RP=R2
270 IF I く 8 THEN AD = &H 4000 ♦I<&H800 ELSE AD = &H4050+(I-8> 本 &H800
280 OUT AD f LP:OUT AD-f 1 f RP : , DRAW PATTERN
290 NEXT
300 GOTO120 : 1 LOOP
310 *
320 'READ FROM ROM
330 OUT &HE82,1
340 R1=INP(&HE80)
350 R2 = INP(&HE81)
360 OUT &HE82,0
370 RETURN
これにより,「漢字 ROM 内のテーブル」を使って,本当の「漢字パターンの ROM 内ア
ドレス」が分かるのである。これについては,表 3-1 を見ていただきたい。これは参考文
献1からの引用である。
結局そのようにして得られた ROM 内アドレス (200 行の変数 R ) を,もう一度 E 80 h ,
E 81„ 番地に指定し,漢字パターンの読み出しにかかるのが,210〜290行である。一度に読
み出すのは2バイトで,それが 16 X 16 の漢字の 横 1ラインになる。結局それを16回繰り
返すことによって,めでたく一つの漢字のパターンとなるのである。なお,270行,280行
第 3 章漢 字 77
表 3-1 漢字 ROM ( CZ -8 KR . 8 KR 2) の I / O ボート
1 0アドレス
入出力
機 能
0 E 82 m
出力
00 h 出力…… ROM からのデータ铳み出し終了
01 M 出力…… ROM からのデータ铳み出し開始
0 E 81 m
0 E 80 h
入出力
1 O (0 E 81 m )-00 h 丨と彡
1 O (0 E 80 H )— JIS 漢字コード上位バイト •
データ読み出し時には.
1 O (0 E 81 H ) からは 00 M
I /0( OE 80 J からは ROM 内アドレス上位バイト
が得られる。
"
1 O (0 E 81 M )— ROM 内アドレス上位バイ K ^ OOm ) 1
1 O (0 E 80 J — ROM 内アドレス下位バイト :
データ统み出し時には,
1 O (0 E 8 lJ からは.右部分フォントパターン16バイト分
1 O (0 E 80 J からは,左部分フォントハターン16バイト分
が得られる。
は簡便にグラフイックの漢字を表示するためのルーチンである0
ところで,先に言っておくが,機械語で漢字 ROM にアクセスする場合は, E 82„ へ01„
を OUT してからデータを読み始めるまでの間(リスト 3-4 の335行にあたる)に 3// S 以
上ウェイトが必要ということになっている(リスト 3-5 参照)。
というところで,駄目押しとして,漢字 ROM にアクセスする機械語ブログラムが リス
卜 3-5 で,それを BASIC から使っているのが リスト 3-6 である。当然なことであるが
turbo では動かない。
リスト 3-5 機械語で漢字 ROM にアクセス
.Z80
.PHASE 0FE00H
•
t
;KANJI PATTERN
READ
;DE
-> JIS-HIGH
t JIS-LOW
FE00
EB
START1 : EX
餐
DE.HL
FE01
56
t
LD
D,(HL)
FE02
23
INC
H し
FE03
5E
LD
JR
E f (HL)
FE04
18 0F
•
t
• mm ^ mm
KREAD
;KANJI PATTERN
DRAW
;DE
-> JIS-HIGH
f JIS-LOW
拳 i i 曹
• • • •
X t Y =16 bits !!!
FE06
EB
START2 : EX
餐
DE f HL
FE07
56
•
LD
D f (HL)
FE08
23
INC
HL
FE09
5E
LD
E f (HL)
FE0A
23
參
INC
HL
FE0B
4E
t
LD
c, (HL)
FE0C
23
INC
HL
FE0D
46
LD
B f (HL)
FE0E
23
•
INC
HL
FE0K
7E
•
LD
A,(HL)
PE10
23
INC
HL
FE11
66
LD
LD
H f (HL)
FE12
6F
L t A
拭験に出る XI
FE15
PE 18
FE1B
FE1D
FE1E
FE21
FE22
FE23
FE24
KE25
FE26
FE27
FE2A
FE2B
D5
FE2C
CD
FEA3
FE2F
44
FE30
4D
FE31
FK32
D9
D1
FE33
CD
FE6F
FE36
01
0E82
FE39
D9
FE3A
AF
FE3B
08
FE3C
3E
10
FE3B
08
FE3F
D9
FE40
3C
FE41
ED
79
FE43
0D
FE44
0D
FE45
00
FE46
ED
78
FE48
OC
FE49
D9
FE4A
ED
79
FE4C
03
FE4D
D9
FE4E
ED
78
FE50
D9
FE51
ED
79
FE53
D9
FE54
FE55
AF
OC
FE56
ED
79
FE58
D9
FE59 0B
FE5A 21 0800
FE5D B7
FB5B ED 4A
FE60 F2 FE67
FE63 21 C850
FE66 09
FE67 44
FE13 1816
JR KDRAW
; 拿 tt 拿拿拿拿 f 拿 t 拿拿
; DE=JIS CODE :
拿拿拿拿拿拿拿拿拿拿拿拿拿
D:HIGH,E=LOW
••READ KANJI PATTERN
•
KREAD : CALL
•
SETROM
* LD
HL.PATA
;PATTERN AREA
LD
A, 16
KREAD い EX
AF,AF 1
;SAVE COUNTER
CALL
RROM
LD
(HL) f D
;GET LEFT
INC
HL
LD
(HL) f E
;GBT RIGHT
INC
HL
EX
AF f AF 1
••CHECK COUNT
DEC
A
JP
NZ f KREADL
RET
•
; DE=JIS CODE :
D=HIGH f E=LOW
; BC=X t HL=Y
;DRAW KANJI PATTERN
•
•
KDRAW : PUSH
DE
••SAVE JIS CODE
CALL
XYADDR
: GET VRAM
LD
LD
B V H
C,L
;COPY ADDR.
; BC=G.ADDR.
EXX
POP
DE
;GET JIS
CALL
•
SETROM
* LD
BC f 0E82H
EXX
•
XOR
A
EX
LD
•
AF f AF f
A f 16
;COUNTER
KDRAWL : EX
AF,AF*
EXX
; BC=0E82H f A=0
INC
A
OUT
(C) f A
;BEGIN READ
DEC
C
DEC
c
NOP
•
;3 U8
* IN
A, (C)
: LEFT
INC
c
EXX
OUT
(C) f A
;DRAW LEFT
INC
BC
EXX
; IN
A,(C)
•RIGHT
EXX
OUT
(C) ,A
;DRAW RIGHT
EXX
#
XOR
A
INC
C
OUT
(C) t A
;END READ
; BC=0E82H f A=0
EXX
; BC=G.ADDR.
;DOWN 1 LINE
DEC
BC
;BACK ADDR
LD
OR
HL f 800H
A
ADC
HL f BC
;CHECK SIGN FLAG
JP
•
P.OKDN
; OK(ONLY BLUE)
•
LD
HL f 4050H
-7800H
;IF WIDTH 40
; LD
HL.4028H
-7800H
ADD
HL f BC
OKDN : LD
B f H
F
6
E
F
D
c
0 F
D 8
E 0 E
FI F
1E8D 23338 D29
230c 727203 cc
D
1
E
F
第 3 章漢 年 73
FE68
4D
LD
•
C f L
FE69
08
* EX
AF.AF 1
FE6A
3D
DEC
A
FE6B
C2 FE3E
JP
•
NZ f KDRAWL
FE6E
C9
* RET
•
t
9 ----%* * * * *
; DE=JIS
FE6F
7B
SETROM : LD
A•E ;LOW
FE70
D6 20
SUB
20H
FE72
6F
LD
•
L f A ; L=LOW-20H
FE73
01 0E80
t
LD
BC,0E80H
FE76
ED 51
OUT
(C) f D ; E80 <- JISH
FE78
0C
INC
C
FE79
AF
XOR
A
FE7A
ED 79
OUT
•
(C),A ; E81 <-00H
FE7C
CD FE8F
* CALL
RROM ;GET FROM TABLE
; DE=TABLE VALUE
參
FE7F
26 00
* LD
H.00H
; HL=JIS LOW-20H :
•
: f TEN f
FE81
29
' ADD
HL.HL
FE82
29
ADD
HL,HL
FE83
29
ADD
HL,HL
FE84
29
ADD
HL f HL ; HL=HLt16
FE85
19
ADD
HL.DE
;NOW HL=ROM ADDRESS
镰
FE86
01OE80
LD
BC.0E80H
FE89
ED 69
OUT
(C) t L ; E80 <- LOW
FE8B
0C
INC
C
FE8C
ED 61
OUT
(C) 9 H ;E81 く - HIGH
FE8K
C9
RET
•
•READ ROM (JUST
2 BYTES)
FE8F
01 0E82
RROM : LD
BC f 0E82H
FE92
3E 01
LD
Ail
FE94
ED 79
OUT
<C),A ;BEGIN READ
FE96
0D
DEC
C
FE97
0D
DEC
C •
FE98
00
NOP
•
;3 U8
FE99
ED 50
# IN
D, (C) ;LEFT
FE9B
0C
INC
c
FE9C
ED 58
IN
E f (C) ;RIGHT
FE9E
AF
XOR
A
FE9F
0C
INC
C
FEA0
ED 79
OUT
(C) f A ;END READ
FEA2
C9
RET
ADDR=4000H^(X1>>3)^((Y1 k 7)<<11)♦(Yl>>3)*80
ADDR=4000H+(BC/8) +((L AND 7)<<11)♦(HL/8) 拿 80
HL=Y1,BC=X1,BREAKS HL t A t BC 9 DE
return HL^addr 9 A^mask 9 D=count
FEA3
7D
XYADDR :
LD
A f L
••SAVE L
FEA4
CD FEC3
•
CALL
DIV8
; HL=HL/8
FEA7
FEA8
54
5D
t
•
LD
LD
D f H
E 9 L
; DE=HL
FEA9
29
t
ADD
HL t HL
•
i
FEAA
29
ADD
HL f HL
; 80=16t5
FBAB
19
ADD
HL,DE
; HL=5
FEAC
29
ADD
HL V HL
;10
FEAD
29
ADD
HL f HL
; 20
FEAE
29
ADD
HL f HL
;40
FEAF
29
ADD
HL.HL
;80 ; HL=(HL/8)t80
;OR
NOP
(WIDTH 40)
FEB0
E6 07
AND
07H
; A=(L AND 7)
FEB2
87
ADD
A, A
FEB3
87
ADD
A 9 A
FBB4
87
ADD
A f A
; A=((L AND 7)<<3)
試験に出る xi
FEB5
FEB7
FEB8
FEBA
FEBB
FEBC
FEBD
FEBE
FECI
FEC2
FEC3
FEC5
FEC7
FEC9
FECB
FBCD
FECF
FED0
ADD A f 040H ;ADD 4000H
LD D f A
LD E 9 00H
;DE = 4000H^((L AND 7)<<(3>8))
ADD HL 9 DE ;LAST 2 & 1ST WERE DONE
EX DE f HL ; HDE=HL (SAVE)
LD
LD
H f B
L f C
; HL=BC
CALL DIV8 ;
ADD HL f DE ;
RET
HL has result (address)•
; HL=HL/8
: BADDR DONE
DIV8 :
SRL
RR
SRL
RR
SRL
RR
RET
PATA :
: PAT AREA
END
リスト 3-5 の中には二つのブログラムが入っている。 FE 00 H 番地からの START 1 は漢
字のパターンを, FEDA „ 番地からの32バイトの領域に読み出すサブルーチンである。それ
に対して, FE 06 H 番地からの START 2 は指定された位置(グラフィック)に,漢字を描く
ルーチンである。このルーチンは手抜きをしてあり,描画は青画面にしかしないようにな
っている。また,普通に考えるなら,「一旦読み出してから描く」のだろうが,それだと面
白くないので, 「 ROM から読み出しながら描く」方法を取っている。
FE 00 H 〜からのルーチンの使い方は, DE レジスタが指しているアドレスから, JIS コー
ドの上位,下位に入っていることが条件である。 FE 06 H 〜は,さらにその後に X , Y の座標
値が入っている必要がある。で,このようにすると BASIC から USR 関数でお手軽に使え
第3聿漢 字75
00 CLEAR &HFE00
10 MEM$(&HFE00 f 16 )=HEXCHR$( M EB 56 23 5E 18 0F EB 56 23 5E 23 4E 23 46 23 7E”>
20 MBM$(AHFE10 t 16) =HEXCHR$ ( ft 23 66 6F 1816 CD 6F FE 21 D0 FE 3E 10 08 CD 8F" >
30 MEM$ (&HFE20 f 16) =HEXCHR$ ( tf FE 72 23 73 23 08 3D C2ID FE C9 D5 CD A3 FE 44 tf )
40 MEM$(&HFE30 f 16) =HBXCHR$ ( f, 4D D9 D1 CD 6F FE 0182 0E D9 AF 08 3E 10 08 D9”>
50 MEM$(&HFE40 f 16)=HEXCHR$( M 3C ED 79 0D 0D 00 ED 78 0C D9 ED 79 03 D9 ED 78”>
60 MEM$ (&HFE50 f 16) =HEXCHR$ ( ff D9 ED 79 D9 AF 0C ED 79 D9 0B 21 00 08 B7 ED 4A M )
70 MEM$ (&HFE60 f 16) =HEXCHR$ ( lf F2 67 FE 2150 C8 09 44 4D 08 3D C2 3E FE C9 7B”>
80 MEM$ (&HFE70 f 16) =HEXCHR$ ( tf D6 20 6F 0180 0E ED 51 0C AF ED 79 CD 8F FE 26 M )
90 MENS (&HFE80 9 16 ) =HEXCHR$ ( 91 00 29 29 29 2919 0180 0E ED 69 0C ED 61 C9 01 tf )
00 MEM$ (&HFE90 f 16) =HEXCHR$ ( tf 82 0E 3E 01 ED 79 0D 0D 00 ED 50 0C ED 58 AF 0C ff )
10 MEM$(&HFEA0 f 16)=HEXCHR$< ff ED 79 C9 7D CD C3 FE 54 5D 29 2919 29 29 29 29 ”)
20 MEM$(&HFEB0 f 16)=HEXCHRS( M B6 07 87 87 87 C6 40 57IE 00 19 EB 60 69 CD C3">
30 MEM$ (&HFEC0 f 16) =HEXCHR$ ( ff FE 19 C9 CB 3C CB ID CB 3C CB ID CB 3C CB ID C9 ff )
40 »
50 WIDTH80 : INIT:CLS 4
60 PALET 1,7
70 DEFUSR0=4HFE00
80 DEFUSR1=&HFE06
90 1 D$ = USR0(HEXCHR$( ff 3E22 ff ))
00 f D$ = USRl (HEXCHRK H 3E22 fi )4MKI$( 10)+MKI$(10))
10 1
20 X=0 : Y=0
30 LOCATE 0 f 0 : INPUT ff JIS tf ; JIS$
40 IF LEN(JIS$)<>4 THEN 330
50 D$=USR1(HEXCHR$(JIS$)+MKI$(X)4MKI$(Y))
60 X=X+16:IF X>640-16 THEN X=0 : Y=Y416:IF Y>200-16 THEN STOP
70 GOTO 330
3-5」 を使う
BASIC
るというわけである。おっと念のために言っておくが,座標として指定する X , Y は Z 80
の16ビット (2 バイト)値で,下位,上位の順になっているわけだ。そして, X の方
は,8ドットごとになっている0つまり,(9, 0) でも(10, 0) でも, (8, 0) に表
示されてしまうのである。いちいちビットシフトなんかやっていられないのである。
さて,サブルーチンをざっと説明しておく 0
SETROM :
DE レジスタに入っている JIS コードの漢字パターンを読み出すための設定をする〇こ
の部分はリスト 3-4 の130〜230行に相当する部分である。
RROM :
漢字 ROM から2バイトだけ読み出すサブルーチン0 D レジスタが左側のパターン , E
レジスタが右側のパターンの相当データを持ってリターンする。 FE 98„# 地の NOP は,そ
の前にある二つの 「DEC C 」 とともに, 3# s のウェイトになるわけである。
XVADDR :
X , Y 座標からグラフィックアドレスを求めるサブルーチンである 0 X 座標は8ドットお
きに限定しているので,なかなか短くなっている。
というわけであるが,最後に付け加えておくと, FE 59„〜 FE 68„ のあたりはグラフィッ
クアドレスを1ライン下げるルーチンである。座標を青画面に限定しているので,このよ
一に短くなっている。
そいでもってリスト 3-6 を実ると, JIS コードを聞いてくる。で,適当なコードを入
れてやるとポコッと表示するわけである。一番気になったのは速度だったのであるが,ど
うやら非常に速いようである。ただしそれは機械語に入ってからのことで,実際にリスト
3-6を走らせても BASIC の部分がどうしようもなく遅いのであった。困ったことよ。
以上,漢字について一とおりやったわけである。しかしながら,この章でやったことは
最小限のことだけである。理想を言えば,せめて単漢字変換ぐらいやっておきたいわけで
あるが,ソフト的なことはまったく棚に上げてしまったわけである。
76 試験に出る XI
#7CPU
(f
MAY
a
WTF5
<X)
サブ CPU のおかげなのである
■第 4 章
^サフ CPU の*かけなのIある • • •
その存在が意識されることは少ないが, XI では,カセッ トのコントロール, キーボード
からの入力,時計,カレンダーはサブ CPU の縄張りになっているのである0てなわけ
で,この章ではその裏方さんのサブ CPU をやるのである。
80C49 な勿 T あ3
まずはサブ CPU そのものについて紹介しておこう。 XI に使われているサブ CPU は,
80 C 48, 80 C 49 という2種類の8ビットワンチッブマイコンである0これらの石はインテル
社の発表した8048, 8049の C - MOS 版なので,型番の間に 「 CJ が入っている。ちなみに
C - MOS の特徴の一つは 消費 電力が極めて少ないということである。そのことによって XI
の電源が OFF になっていてもサブ CPU は生きていて,キーボードからテレビをコントロ
-ルできるのである。さもなくば XI は 電気食い虫になり下がってしま うのであ
る。
それはさておき, 80 C 48, 80 C 49 について基礎 教養 講座を開くのである。
ワンチップマイコンというものは,主に制御用に使われている LSI である0最近では家
庭電気器具にマイコンを組み込むのがはやっていて, CM などでもしょっちゅう自慢して
いるからおなじみであろう。
ワンチップマイコンには4ビットのものと8ビットのものがある(そのうち技術をもて
余したチップメーカーが16ビットや32ビットのものを作るかもしれない)。このビット 数
の違いは,パソコン用の CPU の8ビット,16ビット,32ビットと同じようなものであ
る。早い話が処理能力が違うのだ。 80 C 48 と 80 C 49 はめでたいことに8ビットである。う
っかり4ビット CPU にキーボードをまかせたりしたら,ゲームをするときの キー 操作が
FM -7 のように なっていたかもしれない。 鶴 亀 鶴亀。
さて, 80 C 48 と 80 C 49 の違いであるが,これら二つのマイコンは基本的に同じなのであ
る。序列は 80 C 49 の方が上位(高機能)である。これらのマイコンは,一つのチップの中
に, CPU 部分と, ROM , RAM を持っていて,基本的にプログラムや定数データはすべて
チップ内の ROM に入る。いわばクリーンコンピュータの完全な逆なのである0チップ内
の RAM は主に変数やワークエリアとして使われる。二つのマイコンの違いはこれらのメ
モリの容量で, 80 C 48 の ROM : 1 K バイト , RAM : 64バイトに対して, 80 C 49 ではそれ
ぞれが倍になっている。ただしワンチップマイコンといっても外部に ROM や RAM を付
けることも可能で,そのようにすれば両方とも同じ性能にまで拡張できるそうである。詳
しくは参考文献9を見ていただきたい。
78 試験に出る XI
サブ CPU 勿実態な勿てあ 3
XI でのサブ CPU の使われ方は, 80 C 49 が本体の中にあり,キーボード,カセットデッ
キ,カレンダー,時計 (// PD 1990 という LSI ) と Z 80 との間をとりもっている。 XI のキ
ーボードの中には 80 C 48 が入っており,押されたキーのデータを 80 C 49 がシリアル転送し
ている。これは 80 C 48 ( キーボード)から 80 C 49 ( 本体)への一方通行である。すなわち間
に赤外線の送受信装置などを挟めば,かなり簡単にワイヤレスになるはずである。さて,
turbo のキーボードではちょいと違う。 80 C 48 ではなく, 80 C 49 が使われているのであ
る0これは 「 B モード」なんちゅうものがキーボードに付いたりなどしたため, 80 C 48 では
処理能力が足りなくなったためだと思われる。
turbo で B モードという機能が付いたことからも想像できるように,実は本体内のサブ
CPU の 80 C 49 も, XI と turbo では違うのである。正確に言えば,内部の ROM (マスク
ROM ) に書かれているブログラムが違うのである。さらに, turbo の model 20/30におい
てはそれだけではなく,データレコーダ ( CZ -8 RL 1) をつなぐための変更もある。 8 RL 1 に
も 80 C 49 が内蔵されており,インテリジヱントになっている(確認はしていないが,専用
デ イス ブレイにも入っていると思う) 0 turbo の model 20, 30のサブ CPU は, 8 RL 1 の
80 C 49 同士とシリアル通信を行なっているのである。これは 8 RL 1 をつなぐことができる
X 1 F model 20でも同じことである。すなわち,本体内のサブ CPU は,
1) XI turbo model 20, 30,40 ( II , IH , Z も含む)
2) XI turbo model 10
3) X 1 F , G model 20
4) その他
の 4 種で,それぞれ別の仕様になっているのである。もっと細かい部分や型番なども違う
可能性があるが,少なくとも上記の4種は機能が違っていることは確かである。 8 RL 1 をつ
なげるようにした部分の変更は Z 80 側からはまったく見えない。すなわち,サブ CPU がそ
の部分の「違い」を完全に吸収しているのである。てなわけで,周辺機器の構成の変化に
も対応できる点が,サブ CPU を使うメリットでもあるのだ。
さあ T , 使い方 T あ3
サブ CPU を使うには基本的に2とおりの方法がある。それはサブ CPU からデータを受
け取るか,それともサブ CPU にデータを渡すかの違いである。ただし,どちらの場合でも
最初は Z 80 から 80 C 49 へコマンドを送ってやらなければならない。 80 C 49 はそのコマンド
を見て,自分がデータを Z 80 に送るのか,それとも Z 80 からデータを受け取るのかを判断
するのである。なお,それぞれの場合の受け渡しをするデータ数(バイト数)も決まって
いるので,その数を守らないと正常な動作をしなくなってしまうので注意が必要である。
というところで 表 4-1 にサブ CPU のコマンド表を示す。
第4章サブ CPU 79
表 4-1 サブ CPU コマンドー覧
データ転送方向
画
備 考
Z80 一 80C49
B
turbo のみ。キーボードのモードが A ならデータは 00*.
棚 Misssm
Z80—80C49
n
ベクタを 00 H にすると,割り込みは起きない
E6 h
Z80—80C49
B
データはフアンクシヨン部, ASCII コードの傾
E7 h
Z80—80C49
■■
特になし 1
E8 h
TV コントロール S 充み出し
Z80—80C49
1
TV に最後に送られたコードを技み出す
E9 m
カセツトデッキコントロール
Z80—80C49
1
データは, CMT= — に対応
EA m
カセットデッキ状態 S 充み出し
Z80—80C49
1
データは. ~=CMT に対応
EBh
カセットセンサー統み出し
Z80—80C49
1
データは, ~=CMT(A) に 対応
Z80—80C49
mm
Z80—80C49
mm
EH
Z80—80C49
mm
EF„
時計嫌み出し
Z80—80C49
3
D0 h *^D7 h
タイマ (0 - 7) セット
Z80—80C49
6
特になし
D8 h ~ DF m
タイマ (0 — 7) 嫌み出し
Z80-80C49
6
特になし
では,例によってサンプルプログラムを使いながら順に解説するのであった0
(0) サブ CPU と会話するにも礼儀あり
第 0 章の I/O マッブを見ても分かるように,サブ CPU との会話は I/O 空間の 1900 „番
地を使って行なうのである0しかし,ただ単に 1900„ 番地にデータを IN/OUT すればよい
というものではない。サブ CPU にもサブ CPU の都合というものがあり,おのずと礼儀を
守らなければならないのである。早い話が 1A01 H 番地のビット 6 が 1 (セットされてい
る)ならば,サブ CPU は「今は忙しいからデータは受け取れません」といっているのであ
る。また同じく 1A01„ 番地のビット 5 が 1 ( セットされている)ならば,「今はあんたに渡
すデータはないです」と言っているのである。すなわち,
1 A 01 H 番地のビット6
0 ならば Z80 — 80C49 へ 1 バイト
1ならばダメ
1 A 01„ 番地のビット5
0 ならば 80C49 — Z80 へ 1 バイト
1ならばダメ
なのである。 •
そこで リスト 4-1 を見ていただきたい私なのである。このブログラムを打ち込み間違っ
た場合は暴走したり,キー入力が受け付けられなくなったりするので,実行前に一度
SAVE しておくことをお勧めする。さて,このブログラムはオール. BASIC である。やって
いることはカレンダー(日付)の読み害きなのである0問題の焦点の 80C49 とのデータの
やりとりは,
400 〜 430 行が Z80 — 80C49
80 試験に出る XI
リスト 4-1 オール BASIC 版サブ CPU アクセス ルーチン
100
DATES 二 . .99/02/23"
110
D$ = CHR$UHED> + " • • • : ,GET DATES
120
GOSUB ,# GET-DATA M
130
GOSUB"DISPHEX":PRINT
140
9
150
D$=CHR$(&HEC f &H85,&H93 f &H18) : 1 DATE$= M 85/09/18 M and WED
160
GOSUB”SET-DATA”
170
END
180
»
190
LABEL M DISPHEX M
200
FORI=2TOLEN(D$)
210
D=ASC(MID$(D$ f I f 1)) : PRINT HEX$(D) f
220
NEXT:RETURN
230
9
240
LABEL M GET-DATA M
250
D=ASC(LEFT$(D$ f 1))
260
GOSUB M Z80 - >80C49 M : , SET COMMAND
270
FORI=2TOLEN(D$)
280
GOSUB"80C49->Z80"
290
MID$(D$ f I,1)=CHR$(D)
300
NEXT:RETURN
310
t
320
LABE1/.SET-DATA”
330
D=ASC(LEFT$(D$ f 1))
340
GOSUB M Z80 - >80C49 H : f SET COMMAND
350
FORI=2TOLEN(D$)
360
D=ASC(MID$(D$ f I f 1))
370
GOSUB M Z80 - >80C49 M
380
NEXT:RETURN
390
9
400
LABE し "Z80 - >80C49"
410
WHILE INP(&H1A01)AND &H40:WENDWAIT
420
OUT&H1900,D : f SET 1
BYTE
430
RETURN
440
9
450
LABEL"80C49->Z80”
460
WHILE INPUH1A01) AND &H20 : WEND WAIT
470
D=INP(&H1900) : ,GET 1
BYTE
480
RETURN
450 〜 480 行が 80C49 - Z80
である。ラベルそのものだから別に説明する必要もないのであった。
プログラムではサブ CPU とのやりとりで代表的な二つの形式を示している。まず,
100 〜 130 行がデータ入力である。これは,まずサブ CPU にコマンド ED H を渡して,「カレ
ン ダーの データをちょ 一 だい」と言うのである。サブ CPU は ED„ というコマンドを受け取
ると,「よっしやよっしや」と言って 3 バイトのデータを送ってくれる。 110 行の'••"は
その 3 バイトのデータを受け取るためのダミーである。
次に 150 〜 160 行がカレンダーの セツ トである。最初の EC H が,「これからカレンダーを
セツトするぞ」という意味のコマンドである。サブ CPU はこのコマンドを受け取ると,ま
たもや「よっしやよっしや」と言って 3 バイトのデータを要求してくるのである。そこ
で, 150 行の &H85, &H93, &H18 の 3 個を渡してやるのである。
このサンブルから分かるようにサブ CPU との交信には,
①タイプ1
1 バイトのコマンドを 80C49 へ送る。
その後 80C49 が数バイトのデータを送ってくる。
第4章サブ CPU S 7
② タイプ 2
1 バイトのコマンドを 80 C 49 へ 送る0
その後 80 C 49 がさらに数バイトのデータを要求する。
の2とおりがあるのだ0①を240〜300行のサブルーチン,②を320〜380行のサブルーチ
ンで行なっている。
補足するが,100行では読み出しがいがあるようにデタラメな日付をカレンダーにセツ
卜している0190〜220行のサブルーチンは D $ の中身の表示である0
というところで,いきなり凶器攻擊である。実はこのブログラムはぜんぜん正しくない
のだ0170行を 「 GOTO 110」にしてループさせ,1 BREAK ] キーだけをハイパーオリンピ
ツク的にパシパシと叩くと,やがて BASIC が止まってしまうのである。実はこれはキー割
り込みのせいなのである。そこで機械語を使った正しいサブルーチンを示さねばなるま
い。 リスト 4-2 が240〜480行と同じことをするプログラムのアセンブルリストである〇以
後のサンプル(リスト4-4,5, 6,7, 9) では100〜170行でこの機械語サブルーチン
を使うことになる。
リスト 4-2 サブ CPU アクセスルーチン
• Z80
.PHASE
E000
E003
E006
E007
E008
E009
E00A
E00B
E00E
E011
E012
E013
E014
E017
E018
E019
E01B
E01C
E01D
E01E
E01F
E020
E021
E022
E025
E028
E029
E02A
E02D
E02E
E02F
E030
E032
E033
C3 E006
C3 E01D
FB
EB
56
23
58
CD E034
CD E046
F3
ID
56
CD E034
23
ID
20 F8
FB
C9
FB
EB
56
23
58
CD E034
CD E046
F3
ID
CD E03D
72
23
ID
20 F8
JP
JP
T049 :
T049LP:
FM49:
El
EX
LD
INC
LD
CALL
CALL
DI
DEC
LD
CALL
INC
DEC
JR
El
RET
El
FM49LP:
0E000H
T04 9
FM49
DE, HL
D,(HL)
HL
E,B
SEND1
CANW
E
D f (HL)
SEND1
HL
E
NZ,T049LP
A=COMMAND
INC POINTER
COPY COUNTER
SEND COMMAND
CAN SEND?
DEC COUNTER
GET DATA
SEND 1 BYTE
INC POINTER
DEC COUNTER
FB
C9
EX
DE.HL
LD
D, (HL);
A=COMMAND
INC
HL ;
INC POINTER
LD
E f B ;
COPY COUNTER
CALL
SEND1 ;
ISEND COMMAND
CALL
DI
CANW ;
CAN SEND?
DEC
E ;
DEC COUNTER
CALL
GET1 ;
RECEIVE DATA
LD
(HL) ,D
STORE DATA
INC
HL
INC POINTER
DEC
E
DEC COUNTER
JR
El
RET
NZ f FM49LP
82 試験に出る XI
E034
CD
E046
SEND1 :
CALL
CANW ; SUB-CPU READY?
E037
01
1900
LD
BC f 1900H
E03A
ED
51
OUT
(C),D : SEND DATA
E03C
C9
•
RET
E03D
CD
E050
GETl :
CALL
CANR ; SUB-CPU READY?
E040
01
1900
LD
BC,1900H
E043
ED
50
IN
D f (C) ;GET DATA
E045
C9
•
RET
E046
01
1A01
CANW :
LD
BC,1A01H
E049
ED
78
CANWLP :
IN
A f (C)
E04B
E6
40
AND
40H
E04D
20
FA
JR
NZ f CANWLP
E04F
C9
•
RET
E050
01
1A01
CANR :
LD
BC,1A01H
E053
ED
78
CANRLP :
IN
A, (C)
E055
E6
20
AND
20H
E057
20
FA
JR
NZ,CANRLP
E059
C9
•
RET
1
END
リスト 4-3 正しぃサブ CPU の使ぃ方
100 CLEAR&HDFFF
110 DEFUSR0=&HE000 : DEFUSR1=&HE003
120 MEM$(&HEO00 f 16)=HEXCHR$( t# C3 06 E0 C3ID E0 FB EB 56 23 58 CD 34 E0 CD 46 #f )
130 MEM$(&HE010 f 16)=HEXCHR$( ft E0 F3ID 56 CD 34 E0 23ID 20 F8 FB C9 FB EB 56 M )
140 MEM$(&HEO20 f 16)=HEXCHR$(°23 58 CD 34 E0 CD 46 E0 F3ID CD 3D EC 72 23ID •い
150 MEM$(&HE03O # 16)=HEXCHR$( ff 20 F8 FB C9 CD 46 E0 01 00 19 ED 51 C9 CD 50 E0 tf )
160 MEM$(&HE040 f 16)=HEXCHRS( #I 01 0019 ED 50 C9 01 011A ED 78 E6 40 20 FA C9 ff )
170 MEM$(&HKO50 f 10)=HEXCHH$( i# 01 011A ED 78 E6 20 20 FA C9">
180 1
190 DATE$ = ff 99/02/23 M
200 D$=CHR$(&HED)^ M .•• M : f GET DATES
210 DUMMY$=USR1(D$)
220 GOSUB , # DISPHEX ff : PRINT
230 1
240 D$zCHH$(kHEC $ tLHS5^H93 9 kH\S ): f DATE$ = ff 85/09/18 ff and WED
250 DUMMY$=USR0(DS)
260 END
270 1
280 LABEL”DISPHEX”
290 FORI=2TOLEN(D$)
300 D=ASC(MID$(D$ f I f 1)):PRINT HEX$(D) 9
310 NEXT:RETURN
ここで,当然のことのようにリスト 4-2 を解説するのであった。使い方は リスト 4-3 を
見れば分かると思うが,念のために言うと,
E 000„ がタイプ1(全部 Z 80 — 80 C 49)
E 003„ がタイプ2 (最初の一つ以外は 80 C 49 — Z 80)
のそれぞれエントリーである。 DE レジスタにコマンドとデータ部分へのボインタを, B レ
ジスタにその両方を合わせたバイト数を入れて CALL すればよい。これは BASIC で
USRn (A $ ) を実行したときに セツ トされるレジスタの内容に合わせているので,リスト
4-3 のように手軽に使えるのである。タイプ1,タイプ2両方とも処理の流れは同じような
ものであるから,タイプ1についてだけ処理を追ってみる。
まず E 000 H でいきなり 「 T 049」 へジャンプしてしまう。つまりそこが本当の始まりなの
だ。最初に EI で割り込みを許可している。一見無意味のようだが,これには深い背景
第4窄サブ CPU 幻
と,私の一晩の苦しみが込められているのだ。 XI では動作中ほとんどの場合において割り
込みが許可(つまり EI ) されているのだが,これは主にキー入力のためである。さて,前
にも書いたように,そのキー入力による割り込みもサブ CPU によって行なわれているの
だ。このことからも分かるように,サブ CPU と(キー割り込み以外のことで)交信しよう
とする場合は,割り込みを禁止 ( DI ) しておかなければならないのだ。だが,そのタイミ
ングは凶悪そのものである。すなわち,リスト 4-2 にもあるように,最初のコマンドを送
った後,サブ CPU が「またデータを送ってもいいよ」と言うまで割り込みを禁止してはい
けないのだ。これはタイプ1,タイプ2の両方について言えることである。私はこれを発
見するのに一晚かかってしまった。最後にはとうとう仕方なく HuMonitor を解析して謎
が解けたのである。この取り決めを守らないと,リスト 4-1 での 丨 BREAK 1 キーの速押し
などで動作がその筋してしまうのである。この点のほかは, RET する前に EI を実行する
点以外に特に説明を必要とする部分はないと思う。しかし,縁起ものだから一応言ってお
くが,それぞれのルーチンは,
• SEND 1 : 80 C 49 から 0 K サインが出るまで待って1バイト送る
• GET 1 : 80 C 49 から 0 K サインが出るまで待って1バイト受け取る
• CANW : 80 C 49 へデータを送れるようになるまで待つ
• CANR : 80 C 49 からデータを受け取れるようになるまで待つ
となっている。 BASIC から USR 命令で呼び出す分にはかなり便利だろうと思う(実は
BASIC の IOCS 中にはもっと便利なサブルーチンがあるのだが,それを使うのは軟弱であ
るという私の独断により,一切無視するのであった)。
では,具体的にそれぞれのコマンドについて解説を始める。
① E 3 h (turbo の ゲーム キー 読み取り)
これは turbo のキーボードのスイッチを, 「 B 」 にしたときに発動される秘密兵器であ
る。簡単に言ってしまえば24個のキーを(ほとんど)同時にリアルタイムに読み出せるの
である。24個のキーは固定で,テンキーとメインキーの g ] を中心とした Q 〜 C の8
個,およびその周辺のキーである。具体的にどのキーかということは, 図 4-1 を見ていた
だきたい。
次のサンプルプログラムは リスト 4-4 である0100〜170行はリスト 4-3 の一部分を流用
したものである。230〜250行は後程説明する。このブログラムでは BIN $ を使って,押さ
れたキーに対応するビットを1にして表示する。ループにしてあるのでリアルタイムに変
化する様子をながめていただきたい。充分味わったなら,キーボードのスイッチを 「 A 」 に
していただきたい。何を押しても全部0のままのはずである。すなわちキーボードがモー
ド A のときは何を押しても0が返ってくるのだ。
② E 4„ (キー入力割り込みベクトルセット)
出たっ!とうとう割り込みである。この割り込みというやつはなかなかに面倒臭いの
で心していただきたい。
まずは一般論である。割り込みというのは,一心不乱に仕事をしている人に電話がかかっ
てくるようなものである。その人は電話のベルを聞くと,今どの仕事のどの部分をやって
84 試験に出る XI
キー配置図
ぃたかを覚えておぃて,電話を取るわけである。なぜ覚えておくかとぃうと,電話が済ん
だ後で元の仕事に遅滞なく戻るためである。コンピュータの場合も同じようなもので,
CPU は「それフェッチしてきたぞ。なになに 3 E H だと,よっしゃ,もう1バイト持ってき
て A レジスタにぶち込めばよぃのだな。そうれっ!次は何だ?おっと C 3 H だぜ。今日
はジャンプが多ぃなぁ」などとつぶやきつつ,一心不乱に仕事をしているのである(たぶ
ん)。この CPU に電話,じゃなぃ,割り込みをかけるには, CPU からムカデ状に出てぃる
足に電圧をかけてやればよぃのである。 Z 80 の場合は割り込み用の足を2本持ってぃる。16
第4章サブ CPU 於
00 CLEAR&HDFFF
10 DEFUSR0=&HE000 : DEFUSR 1 =&HE003
20 MEM$(&HE000 f 16 )=HEXCHR$(
30 MEM$(&HE0 10,16) =HEXCHR$(
40 MEMS(&HE020 t 16)=HEXCHR$(
50 MEMS(&HE030 f 16)=HEXCHR$(
60 MEMS(&HE040 f 16)=HEXCHR$(
70 MEMS(&HE050 f 10)=HEXCHR$(
80 1
90 D$ = CHR$(<tHE3)^ M . . . f REA
00 DUMMY$=USR1(DS)
10 GOSUB^DISPBIN"
20 1
30 D$:CHR$(&HE6> , •• ノ •:, READ
40 DUMMY$=USR1(DS)
50 GOSUB"DISPHEX ••: PRINT
60 GOTO190
70 END
80 1
90 し ABE じ DISPBIN"
00 FORI=2TOLEN(D$)
10 D=ASC(MID$(D$ f I t 1)):PR
20 NEXT
30 RETURN
40 1
50 LABEL M DISPHEX ft
60 FORI=2TOLEN(D$)
70 D=ASC(MID$(D$ f I f 1)):PR
80 NEXT
90 RETURN
C3 06 E0 C3ID E0 FB EB 56 23 58 CD 34 E0 CD 46
E0 F3ID 56 CD 34 E0 23ID 20 F8 FB C9 FB EB 56
23 58 CD 34 E0 CD 46 E0 F3ID CD 3D E0 72 23ID
20 F8 FB C9 CD 46 E0 01 00 19 ED 51 C9 CD 50 E0
01 00 19 ED 50 C9 01 011A ED 78 E6 40 20 FA C9
01 011A ED 78 E6 20 20 FA 09^)
•READ GAME KEY
READ NORMAL KEY
: PRINT RIGHT$( ft 0000000 m 4BIN$(D) f 8) 9
) : PRINT HEXS(D) 9
番ピンと17番ピンで,おのおの INT , NMI と呼ばれている0上に横棒(こんなやつ)が
付いているのは,「0ボルトになると効きま一す」という意味なのだ。だから,このピンを
0ボルト(つまり Low ) にすると, CPU に割り込みがかかるのである。の方は例の
リセットキーである ( IPL じゃない方)。こいつは実に我儘で, Z 80 はこの割り込みに対し
て拒否権がないのである。すなわち,
Non Maskable Interrupt
なのだ。 Mask には「邪魔をする」という意味がある 0 Maskable で「邪魔できる」 0 それ
に Non がついて「邪魔できない」。最後の Interrupt は「割り込み」そのものだから,結局
「邪魔できない割り込み」ということになる。う〜ん,いきなり英文読解をしてしまっ
た。
実はこの TOT は XI ではほとんど意味がないので,暇なときに勉強すれば充分であ
る。もっと大事なのが胃で,これがキー入力割り込みベクトルに関係してくる。
さて,この! NT の足が Low にされると割り込みがかけられるわけであるが,こっちに
対してなら Z 80 は拒否権を持っている。先程も出てきた DI である(電話の受話器を外して
おくようなもの)。 Z 80 がこの命令を実行すると,「わしゃ, INT がど一なろうとも知らん
もんね」を決め込むのである。これの逆が EI で,これを実行すると,「私はどんな割り込
みでも受けるっ!」となる。ただし正確には EI の次の命令の実行後である。つまり,
EI
RET
という命令が並んでいると, RET 命令でサブルーチンからリターンした後で割り込みを受
け付けるようになるのである。
それはさておき,こっちの割り込みには3種類があり, Z 80 が自由に選択できるのだ。そ
れぞれモード0,モード1,モード2と呼ばれる(具体的には 「IM 0」, 「 IM 1 J,「IM
2」という見慣れない命令による)。このうちモード0とモード1は8080コンパチなモー
ドである。そして実にセコイのだ。当然のごとく XI ではそんなものは使わないのであ
る。よって,これらの二つのモードについても暇なときに勉強すればよい。というところ
で, INT のモード2の,割り込みにやっとたどりついた私であった。
知る人ぞ知る隠れレジスタというのが Z 80 にある〇 F レジスタと I レジスタと R レジス
夕である。このうち I レジスタ(インタラブトレジスタ)というのがモード2の割り込みで
は主役の一人である。これは8ビットのレジスタである0
モード2の割り込みが発生すると, Z 80 はおもむろにこの I レジスタを見るのだ0次に割
り込み源(誰だっ!俺の!^ T を Low にしたやつは?)からも1バイトのデータを受け取
るのだ(これを割り込みべクトルもしくは割り込みベクタという)〇次に Z 80 は I レジスタ
を上位,割り込みベクトルを下位とする2バイトの数字を作り出し,それをアドレスとみ
なして,その番地に何が書いてあるかを見るのである(見るだけ)。そして Z 80 は そこに
害いてあるアドレスへ サブルーチンコールを起こすのである(正確にはサブルーチン
コールで はないが,ほとんど同じ)〇 XI の BASIC ( turbo は違う)では I レジスタが 00 H
で,キー入力による割り込みべクトルが52„である。そこで Z 80 は0052„番地からの2バイ
86 試験に出る XI
卜に格納されているアドレスに飛んでいくのである。つまり, XI の BASIC では,最終的
に Z 80 は,
PEEK (& H 0052)+ PEEK (& H 0052) * 256 = & H 0346
に制御を移すのである。ここで Z 80 の声を聞いてみるのである。
Z 80 :「おっ!誰でい,誰でい,おいらの INT を Low にするやつは。え一と,今の割
り込みモードは……ああ,モード2になってら。それに割り込みも許可してあら一な。よ
しよし,分かったから割り込みべクトルをよこしな。ふうん,52„ねぇ。まあいいだろ
う。さてと, I レジスタの方はっと……00„ねぇ。となると,ちょいと0052„番地からの2バ
イトをのぞいてみるとすっか。え一となになに,0346„と書いてあるな。そんじゃちょいと
一仕事とくらあ。あらよっ」
となるのであった。
それで結論である。つまりこの E 4„ というコマンドは,そのキー入力用の割り込みべクト
ルを設定するものなのだ。今害いたように, XI の BASIC ( CZ -8 CB 01, FB 01 の Ver
1.0, 2.0 の四つ)では I レジスタが00„,キー入力の割り込みべクトルが52„である 。 turbo
BASIC では I レジスタが F 8„, キー入力の割り込みべクトルが 1 A „ である。
そこで リスト 4-5 のサンプルブログラムを見ていただきたい。これは CB 01, FB 01 用
で , turbo BASIC では動かない。このブログラムは,キー入カベクトルを変えて,0052„
ではなく 0054„番地を参照するようにしている。そこには E 060 H を書き込んであるので,結
局何かキーを押すと, Z 80 は E 060„ K 飛んでくることになる。 E 060„ で手ぐすね引いて待っ
ているのは200,210行にある機械語プログラムである。最後にある「00 30」は変数エリ
アで,この I / O アドレスの所へ65„ (200 行の中程にある)を OUT し,変数を一つ増やし
て(たとえば3000„— 3001„)から本当のキー入カルーチンの3046„番地に飛んでいる。要
するにこのプログラムを1回走らせて 「 OKJ が出ると,それ以後何かキーを押すたびに画
面に re 」 が1個ずつ現れるのだ。正確には,キーを離したときにもキー割り込みが起きる
ので,ボンと1回キーを押すと 「 ee 」 と現れる。変数エリアにある300 0 H はそのたびに増
加するので,しばらく続けるとグラフィック RAM に65„を書き込み始めることになり,
青い点線が画面を トコ ト コ 走るであろう0書き込みアドレスを「00 30」ではなく,最初
から「00 40」にしておくという手もある。打ち間違いがあると当然キー入力ができなく
リスト 4-5 キー割り込みにオジャマ
100
CLEAR&HDFFF
110
DEFUSR0=&HE000 : DEFUSR1=&HE003
120
MEM$(&HE000 f 16)=HEXCHR${
••C3
06
E0
C3
ID
E0
FB
EB
56
23
58
CD
34
E0
CD
46" >
130
MEM$(&HE010,16)=HEXCHR$(
tf E0
F3
ID
56
CD
34
E0
23
ID
20
F8
FB
C9
FB
EB
56” >
140
MEM$(&HE020 f 16)=HEXCHR$(
"23
58
CD
34
E0
CD
46
EO
F3
ID
CD
3D
E0
72
23
lD tf )
150
MEM$(&HE030 f 16)=HEXCHR$(
M 20
F8
FB
C9
CD
46
E0
01
00
19
ED
51
C9
CD
50
E0 ff )
160
MEM$(&HE040 f 16)=HEXCHR$(
tf 01
00
19
ED
50
C9
01
01
1A
ED
78
E6
40
20
FA
C9" >
170
MEM$(&HE050 f 10)=HEXCHR$(
••01
01
IA
ED
78
E6
20
20
FA
C9.
•>
180
i
190
POKE&H54,&H60 f &HE0
200
MEM$(&HE060 f 16)=HEXCHR$(
M F5
C5
ED
4B
74
E0
3E
65
ED
79
03
ED
43
74
E0
Cl")
210
MEM$(&HE070 f 6) =HEXCHR$(
•FI
C3
46
03
00
30.
)
220
i
230
INIT
240
D$=CHR$(AHE4 f AH54) : 'SET KEY
VECT.
250
DUMMY$=USR0(D$)
第4章サブ CPU S 7
なったりするので,リセットスイッチの助けを借りること。
(D E 6„ (キー データの 読み出し)
XI では普通キー入力には割り込みを使うわけだが,別にその方法に限定されているわ
けではないのである。割り込みを使わずにキーを読むには,サブ CPU に E 6„ を送った後2
バイトのデータを受け取ればよい。データの内容は 図 4-2 に示すように,最初の1バイト
がファンクシヨン部と呼ばれるもので,早い話が BASIC の INKEY $(2) と同じであ
る。次に受け取る1バイトが ASCII コードそのものである。リスト 4-4 の230〜250行がサ
ンブルである。このブログラムは割り込みと共存しており, IBREAK ! キーを押すと
BASIC が一瞬停止するので,その状態を見ることはできない。 I SHIFT 1+1 BREAK | も同
様である。
図 4-2 キーボードからのデータの内容
1バイト目
フアンクシヨン部
ファンクシヨン部のデータ
D , D $ D ) D2 Di D 。
T
P
R
G
し
K
S
C
2バイト目
ASCII つード
ビツ
得られる情報
T
P
R
G
し
K
S
C
テンキー部からの入力
キー入力
リビート機能の有無
GRAPH キーの 入力
LOCK キーの 入 刀
力
キーの入力
SHIFT I キーの 入力
CTRL キーの 入力
0
有/1
無
0:
有/1
無
0:
有/1
無
0
有/1
無
0
有/1
無
0
有/1
無
0
有/1
無
0:
有/1
無
さて,実はこのファンクション部は XI と turbo では少々違うのである。 XI では有効な
キーが押されていなければ,ファンクション部は常に FF h (ビットが全部 1) なのだ
が, turbo ではビット4〜〇 (図 4-2 の G 〜 C ) の5ビットが有効なキーが押されていなく
とも ON / OFF するようになっている。たとえば turbo で 「SHIFT | キーだけを押して
も,それを検知できるのだ。確認する方法は簡単で,
10 PRINT ASC ( INKEY $(2))
20 GOTO 10
を RUN すればよい。キーボードのモードが A , B いずれでも同じである。この部分は(お
そらく唯一の)非コンパチ部分であろう。モード A のときは XI と同じになるようになっ
ていれば天晴だったと思うが,実害はないようなので許してしまうのである。
88 試験に出る XI
ところで,当然割り込みを使った場合も示す必要があるが,ちょいと様相が異なるので
最後に回すことにする。
④ E 7 „ f E 8„ ( TV コントロール/桄み出し)
E 7„ は大体 BASIC の CRT , TVPW , CHANNEL , VOL コマンドに対応する。しかし
BASIC の命令ではサポートされていない機能のチャンネルコール,チャンネルの順/逆送
りなども実行できるのである。 E 7 H の次のデータが行なうコントロールを 図 4-3 に示す。サ
ンブルプログラムは リスト 4-6 である0これは入力されたデータを16進数とみなして E 7 h
に続けてサブ CPU に送るものである。事前に CRT のスイツチを切ってから「¢3」を押す
などして楽しんでいただきたい。このブログラムでは,「.」を入力すると E 8 H コマンドを使
ってサブ CPU からデータを受け取り,表示するようになっている。まかり間違っても 「 E 8„
コマンドは最後に実行された E 7„ コマンドで送られたデータを返すだけ」などとは思わな
図 4-3 TV コントロ ールの内容
03,
05,
06,
08,
09,
0 A ,
0 B ,
0 C ,
0D t
0E 卜
10 .
音置ダウ
ル(トグル) ( turbo のデ
イ CZ -850 D などのみ)
TV 画面
不明。なぜかチ
•r
■
V / C 0 M 画面 (
ル(トグル) ( turbo の
イ CZ -850 D などは受け付けな I
I
ンネル) ( S 送
ル逆送
ーオフ
ウン(一気型)
80„
TV 画面
COM 画面
TV パワ
3 A h と 1 F h , ON と 1 E H は基本的に同じ動作だが,一氕型の方が索早くスーパーインポーズになる c
35„と 1 C H の違いは不明。
31„〜 1 F „ のデータに 80 H を加えたものは, TV パワーオン後にそれぞれの動作をする。たとえば86
= 80„ + 06 hU . TV パワーオン後に音声ミユートする。
第4章サブ CPU 卯
100 CLEAR&HDFFF
110 DEFUSR0=&HE000 : DEFUSR1=&HEO03
120 MEM$(&HEO0O f 16) =HEXCHR$ ( ft C3 06 EO C3ID K0 FB EB 56 23 58 CD 34 E0 CD 46 ft )
130 MEM$(&HE010 f 16) =HEXCHR$ ( ## F0 F3ID 56 CD 34 E0 23ID 20 F8 FB C9 FB EB 56 ]
140 MEM$(&HEO20 f 16) =HEXCHR$ ( M 23 58 CD 34 E0 CD 46 EO F3ID CD 3D E0 72 231D M )
150 MEM$(&HEO30 f 16) =HEXCHR$ ( ft 20 F8 FB C9 CD 46 EO 01 00 19 ED 51 C9 Cl) 50 E0 M )
160 MEM$(&HE04 0 f 16) =HEXCHR$ ( f, 01 00 19 ED 50 C9 01 011A ED 78 E6 40 20 FA C9 M )
170 MEM$ ( &HE050 f 10 ) =HEXCHR$ ( ff 0 1011A ED 78 E6 20 20 FA C9”>
180 f
190 INPUT A$ :IF A$ = ff . ff GOTO 240
200 C0DE = VAL( f, &H ft 4AS)
210 D$=CHR$(4HE7 f CODE) : DUMMY$=USRO(DS) : BEEP
220 GOTO190
230 1
240 D$=CHR$UHE8) ♦” •”
250 DUMMY$=USR1(D$)
260 GOSUB ,f DISFHEX ft : PRINT
270 GOTO190
280 f
290 LABEL tf DISPHEX ff
300 F0RI=2T0LEN(D$)
310 D=ASC(MID$(D$ f I f 1)):PRINT HEX$(D) f
320 NEXT:RETURN
いように。 E 8„ コマンドは,あくまでサブ CPU から TV に最後に送られたデータを返すの
である。もちろん E 7„ で送られたものもこのうちに入るが,キーボードを使って TV をコ
ントロールした場合(たとえば r ^ niFn + m ) も tv に送られたデータになるのだ(こ
の場合は10,,になる)。さらに TV タイマの実行時間がきて TV コントロールが起こった場
合も同様である。この点を心得ておくように。
⑤ E 9„, EA h (カセットデッキコントロール/状態読み出し)
E 9 h , EA „ は実に単純明解なことに BASIC の CMT 命令と同じである。マイナーな命令
だから知らない人もいるだろうから,そのよ一な場合はマニュアルを読んでいただきた
い。すなわち,
E 9 H は CMT = x x
EA „ は〇〇 = CMT
に対応する。
早い話がこれだけのことなのだが,偶然にも私は X 1 D の BASIC のマニュアルでは
CMT コマンドの説明が違うことを発見してしまった。すなわち X 1 D では外部テープデッ
キのリモートの ON / OFF ということになっているのだ。
⑧ EB „ (カセットセンサー読み出し)
これは BASIC の CMT (△) 関数に対応している。 図 4-4 と BASIC のマニュアルを見
比べていただきたい。なお,例によって X 1 D の BASIC マニュアルにはこれに対応するも
のはない。
⑦ ECh , ed „ (カレンダーセット/読み出し)
BASIC の DATES , DAY $ に相当するものである。データの内容は 図 4-5 に示すような
形式になっている。
図にあるように,1バイト (8 ビット)を上下4ビットずつに分けて,それぞれの4ビ
ットで〇〜9までの数値(だけ)を指定し,結局00〜99 (10 進数)を表現する方法を BCD
(2 進化10進数)という0なにやら面倒臭いが,早い話4ビットなら〇〜15までの数値を
90 試験に出る XI
図 4-4 カセツトセンスデータの内容
Dj Ds D$ D 4 D 3 D ; D| Dn
テープ停止中
テープ回転中
テープがセットされていない
テープがセットされている
畫防止用のツメを折っていない
録音防止用のツメを折ってある
図 4-5 カレンダーデータの内容
表現できるところを〇〜9に制限して,その代わりに(ある意味で)扱いやすくしようと
いうものである。この場合において最大の利点といえば,サンブル(リスト 4-3) にもあ
るように 「& H 」 や 「 HEX $」 を使い16進数のつもりで10進数を扱える点である。以上の
説明でも理解できないなら,これでど 一 だ。
r 3 バイトがあるのではなく,4ビットが6組あると思え」
さて,すぐ思いつくのが,「17月48日」などのめちゃくちゃな日付を設定するとどうな
るかである。結果は日付がめちゃめちゃになるだけで,特に面白いことは起こらないよう
である。夜中の12時を過ぎると,存在しうる日付に訂正されてしまう。なお,大晦日を過
ぎても「年」は増加しない。また,言語道断の悪習,閏年はサポートされていない。
最後に一言注意。日付などは,夜中の12時になると,その瞬間に更新されるのではな
く,数秒の遅れがあるようである。これを避けるためには,日付を読み出す直前に時計の
読み出しをすればよい。そうすれば自動的に日付も時計が示すとおりに更新されるようで
ある。
第4章サブ CPU 0/
8 EE h , EF „ (時計セット/统み出し)
BASIC の TIMES に相当するものである。形式は 図 4-6 に示すとおり。
時,分,秒の数値を範囲を超えて設定しても,たちまち正常な値に訂正されてしまうよ
うである。
図 4-6 時計データの内容
1バィト目=時
2バィト目=分
3バイト目=秒
D? D$ Ds D 4 D 3 D? Di D 。
10の位 1の位
川 .1 丄 M .
10の位 1の位
10の位 1の位
( X は無効)
注争当たり前だが.時は〇〜 23. 分と秒は〇〜59の値を指定する。
⑧ D 0„ 〜 D 7„, D 8 H 〜 DF H (タイマセット/読み出し)
いよいよサブ CPU のコマンドも最後である。しかしここで気を抜いてはいけない。なぜ
かというと,この TV タイマは隠れ機能の宝庫だからなのだ。そのへんは参考文献8が詳
しいようである。
まず図 4-7 を見ていただきたい。いきなり出てくる「対象は割り込み」である。そうな
のである。このタイマは TV のコント ロール だけではなく,割り込みやカセットデッキの
コント ロール もやってしまうのである。しかも,何に使ってよいやら理解に苦しむインタ
ー バル機能まである。では,おもむろに始めよう。
気付いた方もいるだろうが,実は XI のタイマは全部で8個あるのだ。ところがぎっちょ
ん, ASK コマンドなどでタイマ設定モードに入ってもタイマは7個しか表示されない。す
なわち,「タイマ0」は隠れタイマなのであった。しかも ASK で設定できるのは TV コン
トロールのみで, さらに挙げ句の果てにはそのコント ロール も 90 H 〜 9 B „ および 0 D „ (パワ
一 OFF ) だけなのである0インターバルというのは,タイマに設定された時刻がきたらま
ず普通に (TV OFF などを)実行し,その後はインターバルに指定された「分」ごとに同
じ動作を繰り返すというものである。たとえばインターバルを1分に指定し,動作を音声
ミュートにすると, この 動作はトグルだから,1分ごとに TV の音が出たり出なくなった
りするわけである。いたずらして友達を笟かせようとしているのはあなただけではない。
次に D 7 , D 6 を見ると,「10」で対象が割り込みとなる。すなわちこの場合は,タイマに
設定した時刻になるとサブ CPU から割り込みがかけられるのである。もちろんインター
バルも有効である。このおいしそうな部分は後程ゆっくりと料理する。 D 7 , D 6 が「11」で対
象がカセットテープになる。っまり,設定された時刻になるといきなりテープが回り出す
わけである0コントロール内容は E 9„ で使えるものがすべて OK だから,突然録音状態に突
92 拭 験に 出る XI
図 4-7 タイマ投定/読み出しの内容
1バイト目=コントロール対象とインターバル
♦インターバル (1 〜59分)(実のところ60.61も 0 K
のようである)0のときはインターバル無効。
D 7 d 6
0
0
タイマ無効
0
1
対象は TV
1
0
対象は割り込み
1
1
対象はカ セツ トデッキ
2パイト目=コント ロール 内容
♦対象が TV の場合はコマンド E 7 H 用のコントロールそのもの。
♦対象が割り込みの場合は割り込みべクトル。
•対象がカセットデッキの場合はコマンド E 9 h 用のコントロールそのもの。
3バイト目=分(〇〜 59 J
♦時計の「分 j と同じ,
4バイト目=時(〇〜 23 m )
•基本的に時計の「時」と同じ。 FF„ を設定すると.無効( XX )になる,
5 バイト目=月 (1 〜 C M ), s « 日 (0 〜 6 J
♦基本的にカレンダーの「月」,「墦日 j と同じ。
♦月は 0 M . %•日は F M を指定すると,それぞれ無効( XX または XXX )になる。
6バイト目=日(卜3し)
•基本的にカレンダーの「日 j と同じ。〇〇„を指定すると,無効( XX )になる。
入するなどという凶悪な事態も存在し得るのである。お 一 こわ。
そのよ一な状態であるから,もし万が一,暴走によって
タイマが異常にセットされた
ならば,ゲームがいきなり止まってしまう,などということがあり得る。そのよ一な症状
がある場合には次のようなおはらいをしていただきたい。
1) 本体與面にあるメイン電源スイッチを OFF にする。
2) ポンポンと2回柏手を打つ0
3) メイン電源スイッチを ON にする0
以上でサブ CPU に設定されたタイマはすべてクリアされる。
先程も害いたように,タイマ〇は ASK コマンドによるタイマ設定モードにおいても表
示されない隠れタイマであるから,そのよ一な意味も含めて1か月に一度ぐらいは以上の
ような おはらいを励行してもよい のではないかと思う私であった(タイマ LED がつ
いていないのにやるのもナンだけど) 0
というところで,サンプルプログラムは リスト 4-7 である。やっていることは,まず230
行で日付と時刻を9月18日の16時10分55秒にしている。タイマ1は,16時11分に設定
されており,動作は08„の TV / COM 画面トグルである。タイマ2は割り込みで, 「& H 80 +
第 4 章サブ CPU
100 CLEAR&HDFFF
110 DEFUSR0=&HE000 : DEFUSR1=&HE003
120 MEM$(&HE000 f 16)=HEXCHR$( ft C3 06 E0 C3ID E0 FB EB 56 23 58 CD 34 E0 CD 46">
130 MEMS(&HE010 f 16)=HEXCHR$( ## E0 F3ID 56 CD 34 E0 23ID 20 F8 FB C9 FB EB 56 tf )
140 MEM$(&HE020 f 16) =HEXCHR$ ( tf 23 58 CD 34 E0 CD 46 E0 F3ID CD 3D E0 72 231D">
150 MEM$(&HE030 f 16) =HEXCHR$ ( t# 20 F8 FB C9 CD 46 E0 01 00 19 ED 51 C9 CD 50 E0 M )
160 MEM$(&HE040 f 16)=HEXCHR$( M 01 00 19 ED 50 C9 01 011A ED 78 E6 40 20 FA C9">
170 MEM$(&HE050 f 10 ) =HEXCHR$ ( M 01 011A ED 78 E6 20 20 FA C9 if )
180 1
190 POKE &H54 f &H60 f &HE0: f SET INT\ TABLE
200 MEMS (&HEO60,10) =HEXCHR$ ( ft F5 3E 0132 70 E0 FI FB ED 4D fi )
210 POKE &HE070 t 0: f INIT INT. FLAG
220 CLS4 : WIDTH80
230 DATE$ = M 85/09/18 ,f : TIME$ = tf 16 : 10:55”
240 1
250 D$=CHR$(&HD1 f &H40 f &H8 f &H11 f &H16 f &H9F t AH 18) : f COM. SCR- ON 16:11:00
260 DUMMY$=USR0(D$)
270 D$=CHRS(4HD2 t &H80-fl f &H54 f &H 12 f &H 16 f &H9F t &H 18 ) : INTERRUPT ON 16 : 12:00
280 DUMMY$=USR0(D$)
290 D$=CHR$UHD3,&HC0,«tH0,&H13,&H16,&H9F,&H18> : f EJECT ON 16:13:00
300 DUMMY$=USR0(D$)
310 »
320 D$=CHR$(&HD8 + 4 い ” . ff : f READ TIMER
330 DUMMY$=USR1(D$)
340 GOSUB..DISPHEX ••: PRINT
350 1
360 ADR=&HE07O : KAISU=0
370 LOCATE 0 f 1 : PRINT TIMES
380 IF PEEK (ADR) THEN POKE ADR f 0 : KAISU = KAISU-f 1 : 1 CHECK INT.
390 PRINT KAISU2 1 ヮリコ ミ ノカイスウ
400 GOTO 370
410 END
420 1
43C LABEL M DISPHEX #i
440 FORI=2TOLEN(D$)
450 D=ASC(MID$(D$ t I f 1)):PRINT HEX$(D) f
460 NEXT:RETURN
1」となっていることから分かるように,1分のインターバルを指定している。すなわ
ち,16時12分以降1分ごとに割り込みがかけられるわけである。タイマ3はカセットの制
御で,16時13分に EJECT が行なわれる。 TV コントロールとカセットの制御は見れば分
かるだろうから,タイマによる割り込みを少し説明する。割り込みべクトルは54„であ
る。すなわち割り込みが発生したら0054„番地に書かれているアドレスへ飛ぶ。そこで190
行では,その飛び先である E 060„ を書き込んである0実際に割り込みを処理するルーチンは
200行にある。実に簡単なブログラムで,
PUSH AF
LD A , 1
LD (0 E 070 „),A
POP AF
El
RETI
となっている。これにより割り込みがかけられると E 070„ 番地に1がセットされる。そこで
割り込みが発生したかどうかをチェックする BASIC プログラムが360〜400行の無限ル
ープである。ずっと E 070„ 番地の内容を PEEK を使って見張ってぃて,1がセットされた
ら検知するようにしている。
さて,正しいその筋の読者はここであるアイデアを思いつかなければならなぃ。つま
り,「16時12分に割り込みがかかったなら,その割り込み処理ルーチンの中で,時計を16
94 试験に出る XI
時 11 分 59 秒に設定すれば,その1秒後にまた割り込みがかかるに違いない。時計は狂っ
てしまうが,分単位ではなく秒単位で割り込みをかけることができる!」。
ところが残念ながら,そうはいかない。時計をしょっちゅう読み出し続けていれば(た
とえば , PRINT TIMES の繰り返し ) 2秒ごとの割り込みなども可能なようだが,さもな
くば1分未満の間隔での割り込みは(まともには)無理のようである。
さらに複数のタイマが同時に割り込みを起こす場合もあり得るが,そのような状況に対
してはなんらかの優先順位に基づいて,ちゃんとそれぞれ割り込みを起こすようである。
最後になったが, リスト 4-8, 4-9 である。リスト 4-8 はキー割り込みの処理ルーチン
のアセンブルリストである。見て分かるように,実はこの場合はキーデータを読み出すの
に際して,サブ CPU にコマンド E 6„ を送っても送らなくてもよいのだ。また, turbo では
RETI する前に,サブ CPU に E 3„ を送ってやればゲームキーも読める。リスト 4-9 がこの
ルーチンを使ったサンプルである。割り込みべクトル 54 H を使い, E 060 H 〜のルーチンでキ
一入力を処理している。を押すとべクトルを52„にして終わる。 BASIC では,バッ
ファを持っていて,キー入力をためておくことができるのだが,このルーチンではそんな
ことはせずに, E 080„. 地からの2バイトにファンクション部と ASCII 部のデータを書き
込んでいるだけである。
てなわけであった0いざ自力でオールマシン語のゲームでも作ろうとすると,サブ CPU
は案外, 避けて通れぬ ドラゴンだったりする。この章を 嚙 みしめて,力一杯その筋して
いただきたい。
リスト 4-8 キー割り込み処理ルーチン
.Z80
•
.PHASE
0E060H
E034
SEND1
EQU
0E034H
E03D
GET1
EQU
0E03DH
E080
KEYSTR
EQU
0E080H
E060
F5
INTK :
PUSH
AF
E061
C5
PUSH
BC
E062
D5
PUSH
DE
E063
E5
•
PUSH
HL
t
•
t
LD
A f 0E6H
; D=COMMAND
•
•
•
CALL
SEND1
;SEND COMMAND
E064
IE 02
I
LD
LD
E.2
E066
21 E080
HL,KEYSTR
E069
CD E03D
DATA2 :
CALL
GETl
;RECEIVE DATA
E06C
72
LD
(HL) f D
;STORE DATA
E06D
23
INC
HL
E
: INC POINTER
E06E
ID
DEC
: DEC COUNTER
E06F
20 F8
•
JR
NZ,DATA2
E071
El
•
POP
HL
DE
E072
D1
POP
E073
Cl
POP
BC
E074
FI
POP
AF
E075
FB
El
E076
ED 4D
•
RETI
t
END
第4 章 サブ CPU 仍
100 CLEAR&HDFFF
110 DEFUSR0=&HE000 : DEFUSR1 : &HE003
120 MEM$(&HE000 f 16)=HEXCHR$( ff C3 06 E0 C3ID E0 FB EB 56 23 58 CD 34 E0 CD 46
130 MEM$(&HE010 f 16)=HEXCHR$( ff E0 F3ID 56 CD 34 E0 23ID 20 F8 FB C9 FB EB 56
140 MEM$ (&HE020 f 16) =HEXCHR$ ( ff 23 58 CD 34 E0 CD 46 E0 F3ID CD 3D E0 72 23ID
150 MEM$(&HE030 f 16)=HEXCHR$( ff 20 F8 FB C9 CD 46 E0 01 00 19 ED 51 C9 CD 50 E0
160 MEM$(&HE040 f 16)=HEXCHR$( tf 01 00 19 ED 50 C9 01 011A ED 78 E6 40 20 FA C9
170 MEM$(&HE050 f 10)=HEXCHR$( tf 01 011A ED 78 E6 20 20 FA C9 ff )
180 1
190 POKE&H54 f &H60 f &HE0
200 MEM$(&HE060 f 16)=HEXCHR$( M F5 C5 D5 E5IE 02 2180 E0 CD 3D E0 72 23ID 20
210 MEM$(&HE070 f 8) =HEXCHR$ ( ft F8 El D1 Cl FI FB ED 4D”>
220 MEM$(&HE080 f 2) =CHR$(0 f 0) : f CLEAR WORK AREA
230 1
240 INIT
250 D$=CHR$(«tHE4 f &H54) : f SET KEY VECT-
260 DUMMY$=USRO(D$)
270 1
280 PRINT RIGHT$( M 0 M «fHEX$(PEEK(&HE080) ) f 2) t : ^RINT FUNC- PART
290 CODE=PEEK(&HE081)
300 PRINT RIGHT$( tf 0 M fHEX$(CODB) f 2) f : 1 PRINT ASCII PART
310 PRINT#0 CHRS(CODE) :, DISP CHARACTER
320 IF C0DE=&H1B THEN D$=CHR$(&HE4 f &H52) : DUMMY$=USR0(D$) : END: f IF "ESC” END
330 GOTO 280
)
)
)
)
)
)
CTC
CTC は律儀なのである
■第 5 章
ncTc は律儀なの I ある
この章では CTC をやるのである。 CTC とは Counter Timer Circuit の略である 0
まず最初に断っておくが,残念なことに Non turbo の XI には CTC , および SIO , DMA
が付いていない。しかし,オプションの CZ -8 BM 2 を付ければ,そのボードには CTC と
SIO が載っているという次第である ( CTC は CZ -8 BM 2 以外でも,立体視ボード, FM 音
源ボードに載っている)〇この CZ -8 BM 2 は, RS -232 C が1チャンネルとマウスインターフ
ェイスが付いた,なかなかのボードである。 CTC と SI 0 はそのボードの中で主役を演じて
いるわけであるが,はっきり言って,このボードは turbo の CTC , SI 0 周りの機能とほと
んど同じなのである 0 唯一の違いは, I / O アドレスである。第0章でも示したが, turbo で
は,
SIO =1 F 90 h 〜 1 F 93 h
CTC =1 FA 0„ 〜 1 FA 3 h
だったのが, CZ -8 BM 2 では,
SIO =1 F 98 h 〜1 F 9 B „
CTC =1 FA 8„ 〜 1 FAB h
となっただけである0ただしこれは工場出荷時の設定であるから,ショ ー トピンを差し替
えれば turbo とまったく同じアドレスにすることも可能である 0 念のために表 5-1 , 5-2 に
示しておく。
表 5-1 SI 0 アドレス
アドレス
I - j
内 容
L___J
1 F 90„(1 F 98 h )
チャンネル A データボート
^— ■ H
IN/OUT
_ _
1 F 91 h (1 F 99 h )
チャンネル A 制御語
IN/OUT
_
■■■■ - ■
1 F 92 m (1 F 9 A m )
チャンネル B データボート
IN/OUT
1 F 93 h (1 F 9 B m )
|チャンネル B 制御語
IN/OUT
*5-2 CTC アドレス
アドレス
内 容
1 FA 0„(1 FA 8 h )
チャンネル 0
IN /0 UT
1 FA 1„(1 FA 9„)
チャンネル 1( SI 0 チャンネル A 用クロック)
IN/OUT
1 FA 2 h (1 FAA „)
チャンネル 2( SI 0 チャンネル B 用クロック)
IN/OUT
1 FA 3 h (1 FAB h )
チヤンネル3
IN/OUT
98 試験に出る XI
そこでどのよ一な方針でやるかであるが,まずは CTC の割り込みを使って 「タイムシエ
アリングもどき」 をやってしまうのである。本当はそんなたいそ一なことではなくて,音
楽を鳴らすだけなのだが,基本は同じなので大風呂敷を広げて 景気をつけてしまうの
である。
なお,この章では参考文献4があると便利である。
CTC 勿概略 T あ 3
Z 80 CTC には〇番から3番まで,四つのチャンネルがある。ここでいうチャンネルと
は,言ってみればそれぞれが独立した時計/カウンタのようなものである(本当は完全に独
立しているわけではないのだが) 0 ざっと説明すると, XI では,これら四つのチャンネル
は二つのグループに分かれる。すなわちチャンネル〇, 3とチャンネル1, 2である。
XI ではチャンネル0, 3は主にタイマとカウンタに使われている。早い話が Z 80 に対し
て一定時間ごとに割り込みをかけてくれるのである。一定時間ごとに割り込みをかけてく
れるとどのよ一なメリットがあるかというと,たとえばこれからやるような,音楽を鳴ら
す場合である。つまり, Z 80 が別のことに熱中をしていても, CTC が「あなた,そろそろ
PSG さんに次のデータを渡す時間ですよ」などと教えてくれるのである。つまりは秘書の
ようなものなのだ。秘書がいなければ,自分でしょっちゅう時計を見ていなければいけな
いし,うっかりすれば決められた時間を過ごしてしまうかもしれないのである。チャンネ
ル0,3はそのように使われているのである。
それに対して, XI ではチャンネル1, 2は SIO につながれている。具体的に何をしてい
るかというと, RS -232 C は300 bps とか,1200 bps とかの転送速度があるが,そのための
基準クロックを作っているのだ。すなわち, XI で SIO を使おうとするなら,まずは CTC
が第一関門になっているのである。そこいらへんのことは,次の第6章でつまびらかにな
るであろう。
CTC な仍 T あ 3
CTC のコマンドはそれほど複雑ではない 〇 図 5-1 にあるようにコマンドは1バイトであ
る0これを,四つのチャンネルに別々に送るわけである。指定した場合は,コマンドの直
後に「タイムコンスタント」と呼ばれる1バイトを送ることもあるし,チャンネル〇に対
しては「割り込みベクトル」を送ることもあるが,結局はそれだけである。
まず, CTC のやることを,ごくごく簡単に説明しておく。最初に, 図 5-2 を見ていただ
きたい。これは CTC の接続図である。 「 CLK / TRGJ とか 「 ZC / TO n 」 などがあるが,こ
れは CTC の端子名である。 「 CLK / TRG n 」 とは「外部クロック/タイマ • トリガ」という
ことで,要するに各チャンネルごとにある入力である。 「 ZC / TO n 」 は「ゼロカウント/タイ
ム•アウト」で,こちらはそれぞれのチャンネルの出力に対応する(ただしチャンネル3
用の ZC / T 0 3 はピンの数の都合によって,省かれている)。
第 5 章 CTC 99
CTC のチ
図 5-1
□
□
□
d 4
— 1~ 1
d 3
d 2
V
Di
\
Do
貢」
D 0 = 常に1にする
チャンネル 0(1 FA 0„) の場合は D 0 = O ならば,割り込みべクトルの
指定と判断される。チャンネル1〜3(1 FA 13„)には割り込みべ
クトルを指定できない。
D ,= リセット
D , = l で動作停止。もし D 2 が1ならば.タイムコンスタントが害き
込まれた後動作開始。
D 2 = 時間定数の有無 _
D 2 = l で次に送る1バイトがタイムコンスタントであることを示す。
D 3 = トリガの有無
このビットはタイマモードにおいてのみ意味がある。
D 3 = l でトリガ ( CLK / TRG ) によってタイマ動作を開始する。一旦動作
を開始したならばトリガは関係ない。 D 4 の説明を参照。
D 4 = エッジの選択
タイマモードのときは, D 3 で使うトリガの方向(立ち上がりか,立
ち下がりか)を決める。 D 4 = l で立ち上がりが有効. D 4 =0 で立ち
下がりが有効となる。
カウンタモードのときは,数えるパルスの方向を決める。 D 4 = 1
ならば立ち上がりを数え, D 4 = 0 ならば立ち下がりを数える 。XI
では CLK / TRG へ入るパルスの立ち上がりと立ち下がりの間隔は短
いので,ほとんど意味がない ( CLK / TRG 。 へはパルスは来ない •
CLK / TRG ,, 〆 こは 2 MHz が来ているので,立ち上がりと立ち下がり
の間 SS は l +2 MHz +2 = 250 ns , CLK / TRG 3 にはチヤンネル0から
ZC / TO 。 が来ているが, CTC の性質としてこのパルスは幅が0の 1.5
倍程度の一山であるから,立ち上がりと立ち下がりの間限は1+
4 MHzXl .5 = 375 ns である)。
D s = プリスケーラの選択
このビットはタイマモードにおいてのみ意味がある。
D s = l でプリスケーラは多 (4 MHz ) を256分割する。 D s =0 で16分
割。カウンタモードではブリスケーラは使われない0
D 6 = モードの選択
D 6 = l でカウンタモード, D 6 = 0 でタイマモードが選択される0
D 7 = 割り込みイネーブル
D 7 = 1でダウンカウンタが0になるたびに割り込みを起こす。
CTC のやることは,パルスを数えることである0数えられるパルスは図 5-2 の 「 CLK/
TRGnJ もしくは,システムクロックの必( XI では 4MHz) である。 CTC の各チャン ネル
には「ダウンカウンタ」というものがあり,最初は「ダウンカウンタ=タイム コン スタン
卜」とするのである(タイムコンスタントは〇〜255を指定してやる)〇各チャンネル
は,それぞれがそれぞれのパルスを数えるのだが,何個かのパルスが来るたびに (1 個,
16個,256個の三つの場合がある)ダウンカウンタを一つずつ減らしていくのである〇そ
して,ダウンカウンタが0になると(最初が0だったならば,256回減らすことにな
る), rZC/TO n 」 から一つパルスを出すのである。つまり,パルスの数を 1/ n にするので
ある。もちろんそれだけではど一しょ一もないので, 「 ZC/TO n 」 からパルスを出すのとい
っしょに, CPU に対して割り込みをかけたりもするのである。ま,これが CTC のやって
いることである。
コマンドは各ビットごとに意味を持っているので, D 7 から順に説明していくのである。
1〇〇 試験に出る XI
図 5-2 XI / turbo における CTC の各チャンネルの構成
4 MHz
チヤンネル〇
CLK TRGc
ZC TO .
CLK/TRG
チヤンネノレ1
チャンネノレ2
ZC TO , I
CLK/TRG,
ZC , TO ,
チヤンネノレ 3
CLK TRG
Vcc ( + 5 V )
2 MHz
SIO チャンネル A 用クロック
SIO チヤンネル B 用クロック
D 7 はダウンカウンタが0になったときに,割り込みを起こさせるかどうかのフラグであ
る。
D 6 はモードの設定である。それぞれのチャンネルに「カウンタモード」と「タイマモー
ド」 のどちらかを設定するわけであるが,「カウンタとタイマはどこがど一違うんでぃ」
と,むっとする人が多いであろう。私もむっとしている。分かりやすく言うと,
「タイマモードでは, CTC に供給されているクロック( XI では 4=4 MHz ) を数える」
「カウンタモードでは, CLK / TRG n という端子に来るパルスを数える」
というだけのことである。
D 5 は D 6 でタイマモードを選択したときにのみ意味を持つ。これは,ブリスケーラの指
定で,例のダウンカウンタの値を勝手に16倍 ( D s =0), もしくは256倍 ( D 5 = l ) する
ものだと思えばよい。なぜそうなっているかというと,タイマモードのときの入力の0
は,一般的に 4 MHz などという高い周波数なので,〇〜255までしかないダウンカウンタ
で数えても,数え終わるのにもっとも長くて 250 nsX 256 = 64 # s しかなく,あまり使い道
がないから,という Zilog の親心だと考えられる(本当の親心ならダウンカウンタを2バ
イトで指定できるようにすり やい いのに。ぶつぶつ)。まあ,ここは ちょっと セコイ部分
である。
D 4 はエッジの選択である。ここは( XI では)重要ではないので,図 5-1 を見ておく
れ〇
D 3 も XI ではあまり重要ではない。
D 2 は次にタイムコンスタントを送るかどうかのフラグである。第8章でやる Z 80 DMA
第5章 CTC 101
の用語で言えば,ポインタビットというやつである0
D 1 はリセットであるが,ちょっと注意が必要である。つまり, CTC はリセットをかけら
れなかったなら,そのときやっている動作を終えてから,新しいコマンドに基づく動作を
開始するのである。よって,リセットは大いに使うべきである。
D 。 は,コマンドの場合には,常に1にしておく 0さもなくば,割り込みべクトルを指定
されたものと解釈される。
割り込みべウトル
CTC では,割り込みべクトルは,チャンネル0に対してのみ指定できることになってい
る(つまり,割り込みベクトルを OUT できるのは 1 FA 0„ 番地にのみ)〇それじゃ,他のチ
ャンネルは割り込みをかけられないのかと,一瞬思ってしまうだろうがご安心0チャンネ
ル0に対して指定すると,他の3チャンネルにも自動的に割り込みべクトルが割り当てら
れるのである。すなわち,連続した四つのベクトル (8 バイト)がまとめて指定されるの
である。ただし,その8バイトには少々制限がある。それはど 一 ゆ 一 ことかというと,チ
ヤンネル0のべクトルは,
& B ????? 000
のよ一に,下3ビットが0になっていなければならないのだ0このとき各チャンネルのベ
クトルはそれぞれ,
1 ->& B ?????010
2 —& B ?????100
3—& B ?????110
となる。
だから単純に,「おっ,ここに8バイト分の空きがある。よしよし, CTC の割り込みテ ー
ブルに使ってしまおう」などということは許されないのだ。つまり,その8バイトの先頭
が,
x x x 8 H か x x x 0 „ (下3ビットが0 )
でなければいけないのだ。この点,注意が必要である。
CTC 访使い方 T あ3
さて,あ 一 だこ一だと説明してきたが, XI の場合はハード的な CTC の使い方が単純な
ので,悩むことはぜんぜんないのである。つまり,本来の CTC は D 3 = 1とすること
で,「信号(トリガ)が立ち上がってから,一定時間後に割り込みをかける」などという機
能があるのだが,そんなことは XI では使えないのである(使う必要もないだろう)。 XI で
の CTC の役割は極めて簡単明瞭で,次の三つに要約できる。
①図 5-2 に示したように, XI ではチャンネル0用の CLK / TRG 。 は Vcc ( + 5 V ) に
つながっている。すなわち,パルスがぜんぜん来ないので,チャンネル0はタイマモード
102 試験に出る XI
で使うしかない0その場合,チャンネル0は, 4// S 〜 16.384 ms ごとに割り込みをかけてく
れる。この時間が短すぎるか,ちょうどビタリの間隔が得られないのならば, ZC / TO 。 が
CLK / TRG 3 に接続されていることにより,チャンネル3をカウンタモードで使ってチャ
ンネル0と組み合わせると,最長4.194304秒の間隔を得られる0また,チャンネル0,3
を別々に動かすことも可能である。
② チャンネル1, 2はそれぞれ SIO のチャンネル A , B のクロックにつながっているの
で,それなりに使ってやる。
ただし,気が向いたならばチャンネル0,3と同じように,割り込みを起こさせること
もできる ( CLK / TRGu には 2 MHz が来ているのでチャンネル0よりも割り込み間隔を
短くできる)。
③ OUT 命令ではなく, IN 命令で CTC にアクセスすると,そのときのダウンカウンタの
値を得られる。ただし,これはあまり使い道があるとは考えられない。
そういうわけで実際に使ってみるのである。最初は,③に示したダウンカウンタを読み
出すのをやってみる。これなら割り込みを使う必要がないので入門としてはおあっらえむ
きである。サンブルブログラムはリスト 5-1 である0
リスト 5-1 ダウンカウンタを表示する
100
OUT
&H1FA0,3
1 チヤンネル 0 RESET
110
OUT
&H1FA1,3
1 チヤンネル 1 RESET
120
OUT
&H1FA2,3
1 チヤンネル 2 RESET
130
OUT
&H1FA3,3
• チヤンネル 3 RESET
140
1
150
OUT
&H1FA0. •
&B1001 11 IOUT&H1FA0, 200 : • チヤンネル 0
SET
160
OUT
&HlFA3 f &Bl 000111 : OUT&HlFA3 f 200 : • チヤンネル 3
SET
170
9
180
PRINTINP(&H1FA0) f INP(&H1FA3) : GOTO180
100〜130行では縁起ものなので,各チャンネルに3を OUT してリセットしている〇次
に150行でチャンネル0に OUT しているのは, & B 00100111 である0
順に見ていくと,
籲割り込みなし
籲タイマモード
•ブリスケーラは256分割
籲無視してよい
争無視してよい
•次にタイムコンスタントあり
•リセット ( D 2 =1だからタイムコンスタントを書き込まれた後で動作開始)
• D 0 だから1
となっている。だから次に OUT している「200」はタイムコンスタントである。160行で
はチャンネル3に & B 01000111 を OUT している。これも順に見てゆくと,
♦割り込みなし
•カウンタモード
第5章 CTC 103
•ブリスケーラは関係なし
籲無視してよい
籲関係なし
•次にタイムコンスタントあり
•リセット ( D 2 =1だからタイムコンスタントを書き込まれた後で動作開始)
• Do だから1
である0150行と同じく,次に OUT している「200」はタイムコンスタントである。
このように CTC を設定してやると,どうなるかというと,
1) チャンネル0はタイマモードであるから,システムクロックの0 (4 MHz , 周期は
250 ns ) を数える 0 プリスケーラが256,タイムコンスタントが200であるから,
ZC / TO 。 からパルスを出すのは,
250 ( ns ) x 256 x 200 =12.8 ( ms )
となる0要するに, 0.00000025 秒周期のパルスをもとにして,0.0128秒周期のパル
スを作っているのである。
2 ) チャンネル3はカウンタモードだから CLK / TRG 3 に来るパルスを数える。そこに
は ZC / TOo がつながっているから,結局 0.0128 秒ごとに来るパルスを数えることに
なる0タイムコンスタントは200だから,1個パルスが来るたびに「200,199,
198,……,2,1」となる。1の次はまた200で,延々とそれを繰り返すのである。
ではぼちぼちと本筋へ入ってゆく。 CTC の本筋といえば,当然ながらタイマ割り込みを
使った「マルチタスク」である。理解に便利なように, CTC の設定を BASIC で書いてあ
る 0 リス ト 5-2 は,「割り込み実行ルーチン」のアセンブルリスト, リス ト 5-3 がそれを使
った例である。
リスト 5-3 を RUN すると 「 OK 」 と表示されたのち,画面に筋が走り出すであろう。し
かしその他はまったく正常な BASIC のコマンド待ちの状態になっているはずである。試
しにリストを取ってみることもできる。その場合はグラフィックが表示されなくなるが,
| CTRL 1 +1^1を押せばまた表示されるはずである。これは遊びのようなサンプルである
が,タイマ割り込みを理解するにはちょうどよいだろう。
では実際に何が起こっているのかを, ねっとりと 解説してみる。
まず,220行でチャンネル0に対してやっていることは,タイムコンスタントが125にな
ったこと以外はリスト 5-1 の150行と同じである。次に230行で58„を OUT している
が,これは D 0 = 0であるから割り込みベクトルの設定である。これにより,割り込みべク
トルが,
チャンネル0は58„
チャンネル1は 5 A h
チャンネル2は 5 C h
チャンネル3は 5 E h
となる。240行にあるチャンネル3の設定は D 7 = 1として割り込みを起こさせている点以
外はこれもリスト 5-1 の160行と同じである。
W 4 試験に出る XI
リスト 5-2 割り込み実行ルーチン
.Z80
•
.PHASE
0E000H
E000
F5
C5
RUNG :
PUSH
AF
EO01
•
PUSH
BC
E002
ED
4B E01D
•
LD
BC,(GADD)
E006
78
LD
a 9 b
E007
FE
40
CP
40H
E009
30
03
•
JR
NC,OKOUT
;BC >= 4000H?
E00B
01
4000
t
•
LD
BC,4000H
K00E
3A
E01F
OKOUT :
LD
A,(GPAT)
E01 1
ED
79
OUT
(C) f A
E013
03
INC
BC
E014
ED
43 E01D
LD
(GADD),BC
E018
C1
F1
POP
BC
E019
POP
AF
E01A
FB
El
E01B
ED
4D
•
RETI
E01D
4000
—
GADD :
DW
4000H
E01F
FF
GPAT :
DB
0FFH
§
END
リスト 5-3 タイマ割り込みを使って BASIC と共走 (turbo BASIC では動かない)
100
OUT &H1FA0,3
ンネル 0
RESET
110
OUT &H1FA1 t 3
•チ,ンネル 1
RESET
120
OUT &H1FA2,3
•チヤンネル 2
RESET
130
OUT &HlFA3 f 3
ン本ル3
RESET
140
9
150
CLEAR &HH00O
160
MEM$(&HE000 f 16)=HEXCHR$( M F5
C5
ED
4B
ID E0 78
FE
40
30
03
01
00
40
3A
IF.. >
170
MEM$(&HE010 f
16)=HEXCHR$( ## E0
ED
79
03
ED 43ID
E0
Cl
FI
FB
ED
4D
00
40
FF">
180
MEM$(&H5E f 2)
= HEXCHR$( f, 00
E0.
•):
•ヮリコミ TABLE
SET
190
i
200
CLS 4 : INIT
210
t
220
OUT &HiFA0 f &B100111
••OUT &H1FA0,
125
1 チヤンネ 40
SET
230
OUT &HlFA0 f &H 58
1 ヮリコミへ • クトル SET
240
OUT &H1FA3 V &B1 10001 11
:OUT &HlFA3 f
125
1 チャンネル3
SET
さて,ちょっと前に戻って180行を見ていただきたい。ここで 005 E „ 番地からの2バイト
の 00h, E 0„ を得き込んでいる。これがチャンネル3の割り込みテーブルである。仕掛けは
これだけである。これでチャンネル3により,
250 ( ns ) x 256 x 125 x 125 = 1(秒)
ごとに割り込みが起き,そのたびに E 000„ 番地から始まるリスト 5-2 の割り込み実行ルー
チンに飛んでくることになる0この機械語ルーチンは見てのとおりに,1バイト (8 ドツ
卜)ずつグラフィックにデータを書き込んでいくだけである。220行もしくは240行の
「125」を「1」に書き換えると書き込みが速くなるので, CLS 4 と追いかけっこするのもま
た楽しからずやである。
実技編てあ3
タイマの割り込みを実用的に使う目的としては次の三つが挙げられるだろう。
①一定の間隔(リズム)で何かをしたいとき
第5章 CTC 105
たとえば turbo BASIC の TEMPO 文ではタイマ割り込みの間隔を変えることにより
音楽の演奏速度を変えている。また,ゲームの最中に流れている音楽が,敵キャラがたく
さん出ているときは遅く,逆に少ないときは速くなったりするのをよく見かけるが,タイ
マを使えばそのようなことを比較的簡単に避けることができる。余談になるが,機械語で
作られたプログラムでは,垂直帰線期間信号や垂直同期信号 ( I / O ポートの 1 A 01„) を使っ
て一定のリズムで BGM を鳴らす手法がある。具体的にどうするかというと,これらの信
号は1/60秒ぐらいの周期で High / Low を繰り返すので,
頻繁にその信号を監視しておき,立ち上がりや立ち下がりを見つけることが
できれば,
1/60秒のリズムを捕えるのである。実際にやっているソフトは,アルシスソフトの「ウイ
バーン」,「リバイバー」などである。ううむ,なんという知恵者なことよ。
② 二つのことを同時にしたいとき
—番よい例が同じく turbo BASIC の MUSIC ◎文である 。 turbo BASIC では MUSIC
@文中の演奏データは(どっかの)バッファに入れておくだけで,実際の演奏はその後に
続く BASIC のコマンドを処理しながら,時々タイマ割り込みを使って,適当なデータを
PSG に送り込むことによって,行なっている。もっと簡単に言ってしまうと,ゲームで
PCG やグラフィックを動かしながら(リズムを狂わさずに) BGM や効果音を鳴らすこと
ができる。
③ 遅い周辺機器を待たずに CPU をフルに使いたいとき
これは②の場合とかなり近いものだが,ひとまず区別しておく。これで一番よくあるの
が(本体側ソフトウェアによる)プリンタバッファである0つまりプリンタの印字速度が
遅いために, CPU がしこたま待たされるのを避けるためのものである。念のために言う
が,プリンタから本体へは READY 信号というものが来ていて,結局は「本体さん,私こと
プリンタにデータを1バイト送ってもいいよ」ということを示す信号なのである0この信
号が「まだダメ」であるなら, CPU は待っていなければならないのだ。そこでプリンタパ
ッファの動作を簡単に説明すると,まずはプリンタに送りたいデータはバッファに入れて
おく。そしてタイマ割り込みがかかるたびに READY 信号をチェックして,「送ってもいい
よ」と言えば1バイト送ってやるのである。要するに「他の仕事をしながら,時々様子を
見る」という使い方である。
④ そのものズバリに時計を作る
一定時間ごとに割り込みを起こしてくれるのだから,その回数を数えていれば時間が正
確に分かるのである。短い方では,1/100秒の測定などは朝飯前である0またメモリが許
す限り長いタイマも作成可能である。たとえば何年,何世紀を1/100秒単位で計ることも
簡単である。
そこでまず,②の BGM からやってみる。対比のために リスト 5-4 にタイマを使わない
場合も載せておく。
説明しよう。最初に並んでいる MEM $ 文は機械語ブログラムなどではなく,演奏データ
である。全部 BASIC なのだから配列にすり ゃ 一いいのに,と思うだろうが,私はしたいよ
106 試験に出る XI
リスト 5-4 BASIC 版 BGM 実行ルーチン
100 CLEAR &HD000
110 MEM$(&HD000,12)=HEXCHR$( M 00 DD 01 01 08 0F
120 MEM$(«cHD00C,12 ) =HEXCHR$ ( M 00 A9 01 01 08 0F
130 MEM$(&HD018,12)=HEXCHR$( M 00 7B 01 01 08 0F
140 MEM$(&HD024,12)=HEXCHR$( M 00 DD 01 01 08 0F
150 MEM$(&HD030,48)=MEM$(&HD000 f 48 ): ,クリカエシ
160 MEM$(&HD060 f 12)=HEXCHR$( M 00 7B 01 01 08 0F
170 MEM$(&HD06C,12>=HEXCHR$("00 65 01 01 08 0F
180 MEM$(&HD078 f 12)=HEXCHR$( M 00 3E 01 01 08 0F
190 MEM$(&HD084,12)=HEXCHR$( M 00 7B 01 01 08 0F
200 MEM$(&HD090,48)=MEM$(&HD060,48 ): ,クリカエシ
210 DEFINT A-Z:CLICK OFF:WIDTH 40:INIT
220 X=20:Y=12:LOCATE X f YrPRINT "A";
230 MPS=&HD000 : MPE=&HD0C0 : MP=MPS : W=0
240 SOUND 7 f &B111000:SOUND 8,0
250 1
10 05
10 05
10 05
10 05
08 00
08 00
08 00
08 00
10 05 08 00
10 05 08 00
10 05 08 00
10 05 08 00
10 05
10 05
10 05
10 05
10 05
10 05
10 05
10 05
260 GOSUB*'SOUND"
270 S=STICK(0) : T=STRIG(0)
280 IF S=0 THEN FOR D=0 TO100 : NEXT:GOTO 360
290 LOCATE X,Y:PRINTSPACE$ ⑴ ; : , ERASE CHAR
300 Yl=Y-( (S + 2)¥3)-f2
310 Xl=X+((S+2) MOD 3)-1
320 IF (X1>=0) AND (Xl<39) THEN X=X1
330 IF (Y1>=0) AND (Yl<23) THEN Y=Y1
340 LOCATE X f YrPRINT "A ”;
350 f
360 IF T THEN END
370 GOTO 260
380 1
390 LABEL"SOUND”
400 IF W THEN W=W-1 : RETURN:'WAIT
410 IF MP=MPE THEN MP=MPS
420 M1=PEEK(MP) : MP=MP+1:M2=PEEK(MP> : MP=MP+1
430 IF M1C&H10 THEN SOUND Ml,M2:GOTO 410
440 IF M1=&H10 THEN W=M2:GOTO 400
450 IF M1=&H11 THEN W=M2 拿 256:GOTO 400
460 PRINT "DATA ERROR":STOP
一にするのだ。で,演奏データの形式だが,これは2バイ トが一 組になっている。規則は
簡単で,
1) 1バイト目が00„〜 0 F „ ならば,それは PSG のレジスタ番号である。 PSG のその番
号のレジスタに次の1バイトが書き込まれる。
2) 1バイト目が10„もしくは11„ならば,それはウェイト(時間つぶし)コマンドであ
る(つまり PAUSE 文のよ一なもの)。1〇„の場合は次の1バイトに相当する時間 , PSG
には何も書き込まれない(消されもしない)。 11 H の場合は長いウェイトである。次の1
バイト X 256 に相当する時間, PSG には何も書き込まれない。
これだけじゃなんだから,110行だけは解説しておく。まずは 00 H , DD H だから,「〇番レ
ジスタに DD „ を書き込め」となる。次にある2組も同じよ一なものである。結局この3組
によって,チャンネル A から「ド」の音が音 M 15 (08 h , DF h ) で出ることになる。しかし
これだけでは音にならない。つまり,一定時間以上鳴らし続けてやらなければ,人間の耳
には「ド」に聞こえないのだ(「プチッ」という音になってしまう)。そこで,次に 10 H , 05 h
でウェイトをおいてやる0その後一度チャンネル A の音量を0にして,もう一度ウェイト
がある。これは MUSIC 文を使ってメロディーを鳴らしたことがある人なら分かるよう
に,音符と音符の間を区切るためのもの,つまりスタッカートである。リスト 5-4 のデー
第5章 CTC 107
夕の仕組みは大体こんなふうになっている。
さて,このブログラムは実に セコ くて,極めて原始的なことしかしていない。つまり,
RUN すると画面の中央に 「 A 」 が表示され,「ドレミドードレミドーミファソミーミファ
ソミー」というセコイ BGM がエンェンと繰り返される。しかし,お立ち会い。テン
キーによって, 「 A 」 は上下左右に動くが, BGM はほとんど乱れずに続くのである。
さっさとネタをばらしてしまうが,これは「キャラクタを動かす」というブログラムが
ループになっているということを利用しているのだ。ど一ゆ一ことかというと,まず,「ド」
を出すならば, PSG をそのよ一に設定してやる。つまり PSG のレジスタの0,1, 8にそ
れぞれの値を書き込んでやる。 、、 SOUND " に GOSUB すると,ウェイト中かもしくはウェ
イトコマンドが見つかるまでは RETURN しないので,最初に'、 SOUND " に GOSUB した
段階で,すでに PSG は「ド」の音を出しているのである。
ウソだと思ったら(思うかな?)265行に 「 END 」 を入れてみるといい。「ド」が鳴り続
<はずである(止めるときは十 fUl )。'' SOUND " から RETURN した後は,キャラ
クタを動かす作業だけをすればよい。ただし,ループの時間 (次に、、 SOUND " に GOSUB
するまでの時間)を,あまり変えないようにすること。これは280行を見てもらえば分か
ると思うが,テンキーからの入力がなくてキャラクタを動かす必要がない場合は, FOR 文
で時間をつぶしている。その他の290〜340行はキャラクタを動かしているだけのルーチン
である。290行は 「 A 」 を消している部分,300, 310行はよくあるテクニックを使った新し
い位置の計算である。320, 330行は画面からはみ出さないようにチェックしてから,新し
い位置を X , Y に代入している。340行はその位置への表示である。
では,2 回目に、、 SOUND " に GOSUB したときはどうなっているかを見てみる。ま
ず,前回のときは ウェイ ト コマン ドを見つけて,その後400行で W = W - 1とした後
RETURN したのである(分かるかな?)。それは440行である。変数 W に2バイト目が
代入された後に,さらに 一 1されたのだから,2 回目に GOSUB してきた時点では W の値
は4である。すると,400行の 「IF W 〜」に引っかかる。すなわち W から1引いて , W
の値を3にしてから RETURN である0これと同じことが W が0になるまで繰り返され
るわけだから,結局,
1回目— PSG は「ド」を出し始める ( W = 4で RETURN )
2回目—何もしない ( W = 3で RETURN )
3回目—何もしない ( W = 2で RETURN )
4回目—何もしない ( W = l で RETURN )
5回目—何もしない ( W =0 で RETURN )
6回目— W =0 だから,次のコマンドを捜す
ということになる01回目と2回目,2回目と3回目,……の間には,270〜370行を実行
している時間がそれぞれ挟み込まれているから,この場合,数えてみるとループ5回分の
間「ド」が出ることになる。よ一く考えると分かることだが,440行,450行で 「GOTO
400」とせずに 「 RETURN 」 とすると,ループ6回分になってしまうので,この手のプロ
グラムを作るときは注意が必要である。
108 試験に出る XI
E000
E001
E002
E003
E004
E007
E008
E009
E00B
E00C
E00F
E011
E014
E018
E019
E01B
E01D
E01F
E023
E024
E025
E026
K027
K028
E02B
• Z80
.PHASE 0E000H
•
PLAY : PUSH AF
PUSH BC
PUSH DE
PUSH HL
PLAY0 :
LD
HL f (WC)
LD
A t H
OR
L
JR
Z f NOWAIT
DEC
LD
JR
HL
(WC) f HL
#
PEND
NOWAIT :
LD
HL,(MPE)
LD
DE t (MP)
OR
A
SBC
HL t DE ; MPE>MP?
JR
C f OVER
JR
NZ,FETCH
OVER :
LD
DE,(MPS)
FETCH :
EX
LD
DE.HL 丨 HL=MP
A f (HL)
INC
HL
LD
E f (HL)
INC
HL
#
LD
(MP) f HL ;STORE MP
»
CP
16
残りの部分を種明しすると, MP は演奏データ(アドレス)を指している変数である。
MPS (データの始まり ), MPE (データの終わりの次)は, BGM を繰り返すためのもの
で, MP が MPE と等しくなったら, MP に MPS を代入してやって繰り返しに入るのであ
る。後は240行であるが,これは本来ならば D 000„ からの音楽データの先頭に,
07h , 28h , 08h , 00h
というように入れてやるべきだったのだが,アドレスがズレてしまって美しくなくなるの
で手抜きをしたのだ。ま,以上である。
すでに気付いたことと思うが,このテクニックを使った場合, BASIC だろうが機械語だ
ろうが,キャラクタを動かすルーチンの部分が多少なりとも複雑になってしまうと , BGM
のリズム(テンポ)を一定に保つのは至難の技なのだ0まず 第一に, ある局面になったら
新しく敵キャラが出てくる場合や,さらにその敵キャラが増減する場合である。その度
に, うまくヒマつぶしの時間を増減させてやらなければならないのだ。実にうっとうしい
話ではないか。
そこで CTC 様がリングに上がるのである。 タイマ割り込みによって変わるのは
次の2点である。
1) GOSUB '' SOUND " をループの中に置かなくてよい(決められた時刻になると,自
動的に GOSUB してしまう)。
2) テンポを一定に保つためのヒマつぶしのルーチンを考えなくてもよい。
なんだなんだ!結局は「音無しのゲームを普通に作る」だけで済んでしまうのではな
いかっ! ということでリスト5-5, 5-6 である。リスト 5-5 はリスト 5-4 のブログラム
をそのまま機械語に置き換えたようなものであるから説明はしない。
リスト 5-5 BGM 用割り込み実行ルーチン
1
5
0
E
5 5 5 5 A
F c D E 2
51
6 0 9
0 E 3
C 5 8 B 2 8
7 B 2 2 21
0 B 2 2 4 B
E 5 5 0 0 5
A D 7 D 8 0 D
2 E B E 3 2 E
0
11
B E 3 E 3 2
E 7 2 5 2 2
第 5 章 . CTC W9
結論てあ 3
以上なわけである。この章のサンプルは, CTC の I/O アドレスを 1 FA 8,, 〜 1 FAB „ にずら
してやれば, CZ -8 BM 2 を装着した XI でも動くはずである。ぜひとも試していただきた
い。また,リスト 5-6 では PSG のチャンネル B , C を使っていないので,第10章のリス
卜 10-3 を少々変えて,チャンネル A をいじらないようにすると, BGM と銃声が共存共栄
するのである。具体的にどうするかというと,リスト 10-3 の120行にある 「& B 000111」
を 「& H 001110」 にすればよいだけなのだ。これでチャンネル A はトーン, B と C はノイ
ズになる。ど 一 だ,すごいだろう。止めるときは, 「OUT & H 1 FA 3, 3」である。
あと CTC の使い方としては時計が代表的なものであるが,以上のことを理解できれば
あっという間に作れてしまうだろう。
no 試験に出る XI
100
140
150
160
170
180
190
200
210 MEM$
220 1
230
340
350
360
370
380 SOUND
390 OUT AH
400 OUT &H
410
ーチン (turbo BASIC では動かない)
嘴語版 BGM 実行
E02D
30 0A
#
E02F
011C00
1
E032
ED 79
E034
05
E035
ED 59
E037
18 D8
•
E039
FE 10
SETWT :
EC3B
20 04 •
E03D
16 00
E03F
18 03
E04 1
53
SETWT1 :
E042
IE 00
E044
ED 53 E051
SETWT2 :
E048
18 BA
#
#
E04A
El
PEND :
E04B
D1
E04C
Cl
E04D
FI
E04E
FB
E04F
ED 4D
#
E051
0000
WC :
E053
0000
MP :
E055
0000
MPS :
E057
0000
MPE :
JR NCtSETWT ;SET WAIT COUNTER
LD BC,1C00H
OUT (C) f A ;SET REG. NOMBER
DEC B
OUT (C)•E
JR NOWAIT
CP 16
JR NZ f SETWT1 ;BIG WAIT
LD D f 0
JR SETWT2
LD D f E
LD E 9 0
LD (WC) f DE
JR P し AY0
POP HL
POP* DE
P BC
P . AF
El
RET I
DW 0000H ;WAIT COUNTER
DW O00OH : MUSIC DATA POINTER
DW 0000H ;MUSIC START
DW 000OH : MUSIC END
HNI)
8 D 18 D 0
1 E 0 1 E 0
o 4 A o B 0
E 0 0 0 F 0
10 0 6 10
5 2 31 F 0
2 2 0 4 10
2 0 1 0 c 0
B 8 E o1 0
2 3 F 2 D 0
6 2 0 0 10
0 5 B 1 E 0
8 D 3 E A 0
2 H 5 F B 0
5 7 2 8 8 0
B B 2 D 1 0
c 0 3 8 0 0
7 E 21 E 0
o 3 E 9 1 0
E 5 5 5 5 o
1 B 3 D 3 0
5 5 2 E 5 0
A D E 5 D 0
2 E 7 0 E 0
5 o B 9 0 0
E E E 7 0 0
5 7 0 D E o
D 5 E E 1 0
5 A 5 c 3 0
c 2 5 1 5 0
5 9 B 0 3 D
F 3 5 0 0 4
なお,あまり勧められた手ではないが , turbo BASIC ではちょちょいのちょいで簡単に
CTC の割り込みを使う手がある。それは, F 81 E „ にある割り込みべクトルを書き換えると
いう手である。割り込み間隔は TEMPO 文で変更できる。この場合もう一工夫しないと
PLAY 文が使えなくなってしまう,などの欠点があるが,手軽さには捨てがたいものがあ
る。実例は12章(カラーイメージボード)に載せてある。
CTC の使い方は限られているが,その応用例は広いのである。そして, CTC だけではど
うにもならないが,大事な基本技として必修なのである。
第5章 CTC 111
SI ◦でマウスである
第 B 章
SI 0 T 7 ウス I おる
この章で取り上げる Z 80 SIO (Serial Input / Qutput ) は,シリアル通信を主な業務とし
ている石である。そして,この石はやたらと複雑で強力なのである。これはとりもなおさ
ず,シリアル通信というものが複雑怪奇であることに由来する。実際にパソコンで通信を
する場合には, BASIC の OPEN 文の通信パラメータで指定するだけの機能があれば済む
のだが, SIO にはそれ以上の機能が盛り込まれているのである。そういうわけで,不本意
ながら SIO の使い方を細かく説明するわけにはいかない。もしも SIO の機能をみっちり
と知りたいならば,参考文献4を読んでいただきたい。
さて,実は Z 80 SIO といっても三つのバージョン(ボンディングオプション)があるの
だ。すなわち,
SIO / O , SICV 1, SI 0/2
である。 XI に使われているのはそのうちの SIO /0 である。これら三つのものの違いは,チャ
ンネル B に対する制限で,早い話がピン数(足の数)に限りがあるのでそうなっているの
である( XI ではチャンネル B はマウスに接続するわけだから,まったく問題ない)〇
SIO にはチャンネル A , B の二つのチャンネルがあり, XI ではチャンネル A が RS -
232 C の通信用で,チャンネル B が今書いたようにマウス用になっている。そして,まずは
この 章でチャンネル B = マウスを先にやった後で,次の第7章でチャンネル A の通信関係
へと 進むつもりである。
7ウス T あ3
XI のマウスは RS -232 C のシリアルマウスで,データの方向はマウス— XI の一方通行
である。マウスから送ってくるデータは,
① ボ ー レートは4800 bps
② コントロール信号を立ち下げる (H — L ) とデータを送ってくる
③ データは一組が 10ビット構成で,
スタートビット=1ビット
データビット=8ビット
ストップビット=1ビット
の10ビットが3組
となっている。③でいきなりスタートビットとかストッブビットとかが出てきたが,これ
がシリアル通信のうっと一しいところである。具体的にどういうシロモノかというと,「は
い,今からデータが行きますよ一」,「はい,これでデータは終わりです」とかいう区切り
なのだ。一般の通信では,データが7ビットだったり,ストップビットが 1.5 もしくは2
1 U 試験に出る XI
図 6-1 マウスからのデータの内容
巨
ステータス
Do
スイツチ 1 の状態
1で ON , 0で OFF
D ,
スイッチ2の状態
D ,
d 3
d 4
X のオーバーフロー ビット (128 以上のとき)
Ds
X のアンダーフロー ビット (一129 以下のとき)
De
Y のオーバーフロービット (128 以上のとき)
D ,
Y のアンダーフロー ビット(一129以下のとき)
2バイト目
3バイト目
X 方向の移動置
一128~ + 127
Y 方向の移動置
■■ j
一128~ + 127
D 7 が符号ビットである
就み出した1バイトのデータが X ならば,
D 7 = 0 —移動置 = X さ0
D 7 = l —移動置 =X — 256<0
ビット(長さが 1.5 倍もしくは2倍なのだ)のこともある。さて,結局マウスからは3バ
イトのデータを送ってくるわけである。その内訳は 図 6-1 である。
まずステータスについて説明する〇 D 。, Di のスイッチは自明だからよいだろう。2 ビッ
卜空いて D 4 〜 D 7 がオーバー/ アン ダーフロー ビッ トである。これはマウス内のカウンタが
あふれたということで,たとえば D 4 =1だったなら,マウスが「おいらはよく分かんない
けど, X 方向に128以上動いちゃった。だから2番目のデータの rX 方向の移動 MJ はあ
てにならないよ」と言っているわけである。以下同様。
次に X / Y 方向の移動童であるが,一番大事なことは,前回データを送ったときからの相
対距離だということである 。 turbo BASIC の M 0 USE (7), MOUSE ( 8 ) に相当するもの
だから, BASIC のマニュアルを見ておくれ。
では リスト 6-1 によって,具体的にマウスを使う方法を示す。恐ろしいことにオール
BASIC である。心得のある人ならば 「4800 bps で30ビットを送ってくるんだから,30+
4800 = 0.00625 秒じゃね 一 か。 BASIC で間に合うの?」と思うであろう。しかし目出たい
ことに, Z 80 SIO はバッファを三つ分(この場合だと3バイト分)持っているのだ。だか
らどんなにゆつくりやっても,マウスからのデータならば取りこぼしがないのである。楽
ちん楽ちん。
リスト 6-1 マウスの使い方,もしくはバッファは3拍子
100 GOSUB”SETCTC&SIO"
110 1
120 OUT &H1F93,5:OUT &H1F 93,0 : , u ント D- ルシンコ•ウヲ H ニスル
130 PAUSE 0 :• チヨットタ • ヶマツ(キフ ‘ ン >
140 OUT &H1F93,5:0UT &H1F93,2 : , REQUEST ( コントロ - ルシン : ! • ウ :: RTS ノ タチサケ • >
150 FOR 1=1 TO 3
160 OUT &H1F93,0 : BBB=INP(&H1F93) AND 1 Z*BUFF ニテ • ータカ • アルカ ?
170 IF BBB=0 THEN 160
180 DDD=INP(4H1F92)
190 PRINT DDD
200 NEXT
第 6 章 SIO 115
210 PRINT STRINGS(10, M = M )
220 GOTO120
230 1
240 LABEL M SETCTC&SIO M
250 OUT &H1FA2,&B 1000111: 1 CTC チャンネル 3 SET
260 OUT &H1FA2,26 : , TIME CONSTANT
270 1
280 RESTORE "SIODATA"
290 F0RI=1T015
300 READ D : OUT&HlF93 f D
310 NEXT
320 RETURN
330 1
340 LABE じ 'SIODATA"
350 DATA &B 00011000
360 DATA 1,0
370 DATA 2,00H
380 DATA 4 f &B 01000100
390 DATA 5 f 00H
400 DATA 6 f 00H
410 DATA 7 ( 00H
420 DATA 3,&B11 000001
1 RESET
f WR0=00H
, WR2 = 00H=INT. VECTOR (turbo ノ ハ • アイ)
, WR4 = 44H= , クロック A *16 1 & ,ストッフ • ヒ •• ノト =1 ヒ•ツト
, WR5=00H
, WR6=00H
t y y -
, WR3 = C1H=,DATA = 8 ヒ • ット , 4 ,イネーフ • ルレシーハ •
さて,リスト 6-1 はしょっぱなから240行へ GOSUB している。これは CTC と SIO の
設定である0まずは250〜260行で SIO のチャンネル B 用のクロックを作っている CTC
のチャンネル2を,「カウンタモードでタイムコンスタントは 26 J にする。これによってチ
ヤンネル2は 2 MHz のクロックを数えるわけだから,
2xl0 6 (Hz)
x 26=13 xl ( T « (秒)
ごとにパルスを出す。 SIO は,このパルスを16もしくは64分周してボーレートにするの
である。この場合は,16分周すれば,
13 x l ( T 6 x 16=208 x 1( T 6 (秒)
となり,結局これは,
208 x 10^ = 4807 . 69…与4800
というしだいである。きっちり4800である必要はないのである。次は280行からである
が,ここで SIO を設定している。やっていることは,
♦キャラクタ長は8ビット
•クロックは CTC からのパルスを16分周
籲ストッブビットは1
籲割り込みなし
などである。
ここを RETURN した後に,いよいよメインルーチンである0120〜140行ではコントロ
ー ル信号を立ち下げているのだが,マウスへのコントロール信号はチャンネル B の RTS
なのである。 RTS とは r Request To Send 」 で,要するに「送ってきてちょ 一 だい」であ
る。これが H — L になると,マウスは律儀に3バイトのデータを送ってくる。130行に
PAUSE 文があるが,これは気分の問題である。 BASIC ならばどうでもよいのだが,機械
語でやる場合はそうはいかない。ある程度の時間 「 H 」 にしておいてから 「 L 」 にしなけれ
116 試験に 出る XI
ばならないのだ0実にやっかいなものだ。
150〜200行の FOR 〜 NEXT 文で3バイトのデータを SIO のバッファから読み出して
表示している 〇 160,170行は「バッファにデータが入っているか」の判定 ルーチン, 180行
がデータの読み出しである。ブログラムを RUN すると3バイトのデータを表示してい
く 0マウスを動かしたり,ボタンを押したりすると数字が変わるであろう。
マウス访実技 T あ3
悲しいことであるが,世の中には「マウスよりもトラックボールがいいのだ」,「うんに
ゃ,ライトペンこそが一等贫!」,「てやんでぃ。タッチパネルを忘れてもらっちゃ困るぜ
ぃ」などと言う人達がいる。あなた達に神の御許しがありますよ一に,というわけで私
はマウス党なのである。
そこで リスト 6-3 , 6-4 をさっさと実行していただきたい。ちなみにリスト 6-3 のソー
スリス トは リスト 6-2 となっ ている。 リス ト 6-3 は チェックサムと CRC 付きのダンプリ
ストである。入力に際して は 付録 A のダンブリス ト チェックプログラムを参照のこと。
第 6 章 SIO 117
EA48
C9
•
RET
EA49
2A EB31
MSGO :
LD
HL,(XI)
;COPY POSITION
EA4C
22 EB2B
LD
(X0) 9 HL
EA4F
2A EB33
LD
HL f (Yl)
EA52
22 EB2D
LD
(Y0),HL
BA55
CD EADC
CALL
CIN
;CHECK IN
EA58
E6 03
AND
3
EA5A
28 05
#
JR
Z f BEGIN
EA5C
3E 02
•
LD
A,2
EA5E
C3 EB16
•
JP
ERR0
EA61
CD EBA5
BEGIN :
CALL
SETMS
;MOUSE INIT
EA64
CD EBD9
•
CALL
PSET
;SHOW CURSOR
EA67
FD 21 EB39
t
LD
IY.MSDATA
EA6B
CD EB49
•
CALL
MSIN
EA6E
3A EB39
BEGIN0 :
LD
A,(MSDATA)
EA71
F5
PUSH
AF
EA72
FD 21 EB39
LD
IY,MSDATA
; IY=POINTBR
EA76
CD EB49
CALL
MSIN
: READ MOUSE
EA79
FI
POP
AF
EA7A
B7
OR
A
EA7B
20 11
•
JR
NZ f BUT2
EA7D
21 EB35
t
LD
HL t BMASK
: CONDITION
EA80
3A EB39
LD
A,(MSDATA)
••GET STAT
EA83
E6 03
AND
3
BA85
06 04
•
LD
B.4
EA87
BE
BUT0 :
CP
(HL)
;CHECK BUTTON
EA88
23
INC
HL
EA89
CA EB11
JP
Z f BUTTON
;BUTTON HIT
EA8C
10 F9
BUT1 :
DJNZ
BUT0
EA8E
21 EB3A
BUT2 :
LD
HL.MSDATA+l
EA91
7E
LD
A f (HL)
EA92
23
INC
HL
EA93
B6
OR
(HL)
EA94
28 D8
JR
Z 9 BEGIN0
; X=Y=0 THEN NO-O
EA96
3A EB3A
•
t
LD
A, (MSDATA+U
EA99
CD EB0A
CALL
XSIGN
EA9C
2A EB31
LD
HL f (XI)
EA9F
19
ADD
HL 9 DE
EAA0
22 EB2B
鎌
LD
(X0) t HL
EAA3
3A EB3B
t
LD
A,(MSDATA^2)
EAA6
CD EB0A
CALL
XSIGN
EAA9
3E 01
LD
A,1
EAAB
BB
CP
E
EAAC
28 04
PATCH3 :
JR
Z f OKl ;1 -> 1
l (-1 -> -1 )
;OR
JR
OKI (WIDTH
40)
EAAE
CB 2A
SRA
D
EAB0
CB IB
RR
E ; DE=DE/2 with sign
EAB2
2A EB33
OKI :
LD
HL, (YU
EAB5
19
ADD
HL f DE
EAB6
22 EB2D
•
LD
(Y0) f HL
;CHRCK
IN?
EAB9
CD EADC
CALL
CIN
EABC
FE 03
CP
3
EABE
28 AE
•
JR
Z f BEGIN0
;X AND Y OUT
EAC0
F5
t
PUSH
AF
EAC1
CD EBD9
CALL
PSET
;ERASE CURSOR
EAC4
FI
暴
POP
AF
EAC5
0F
t
RRCA
EAC6
Y
38 06
JR
C,YCHECK
; X=OB THEN CHECK
EAC8
2A EB2B
LD
HL V (X0)
;COPY POSITION
EACB
22 EB31
•
LD
(Xl) f HL
EACE
0F
YCHECK :
RRCA
EACF
38 06
JR
C.SHOWC
BAD1
2A EB2D
LD
HL, (Y0)
Iis 試験に出る XI
01
EB3C
BBD9
5B EB29
EB31
0018
B0
EB14
EB16
EB19
EB1C
EB20
EB23
EB26
EB28
EB29
EB2B
EB2D
EB2F
EB31
EB33
EB35
EB39
EB3C
EB3D
BB3F
EB40
EB42
EB44
EB46
EB48
EB49 011F93
EB4C 3E 05
EB4E ED 79
KB50 AF
EB51 ED 79
EB53 16 80
BB55 15
EB56 20 FD
EB58 3E 05
EB5A ED 79
EB5C 3E 02
EB5K ED 79
EAD4
22
EB33
EAD7
CD
EBD9
EADA
18
92
EADC
AF
EADD
ED
5B EB44
EAE1
2A
EB2D
EAE4
B7
EAE5
ED
52
EAE7
38
09
EAE9
ED
5B EB2D
EABD
2A
EB46
EAFO
ED
52
EAF2
17
EAF3
ED
5B EB40
EAF7
2A
EB2B
EAFA
B7
EAFB
ED
52
EAFD
38
09
EAFF
ED
5B EB2B
EB03
2A
EB42
EB06
ED
52
EB08
EB09
17
C9
KB0A
5F
EB0B
16
00
EB0D
07
EB0E
D0
EB0F
EB10
15
C9
EB11
AF
EB12
18
02
LD (Y1) f HL
SHOWC :
CALL
PSET ;SHOW NEW CURSOR
•
JR
BEGIN0 ;AGAIN
CIN :
XOR
A
LD
DE f (YU)
LD
HL f (Y0)
OR
A
SBC
HL f DE
•
JR
C,XIN
•
LD
LD
DE f (Y0)
HL,(YD)
•
SBC
HL 9 DE
XIN :
RLA
LD
DE,(XL)
LD
HL 9 (X0)
OR
A
SBC
HL f DE
•
JR
C.XIN0
»
LD
LD
DE,(X0)
HL 9 (XR)
SBC
HL.DE
XIN0 :
RLA
•
RET
XSIGN :
LD
LD
E, A
D 9 0
RLCA
RET
DEC
NC
D ; D=FFH or 00H
•
RET
BUTTON :
XOR
A
•
JR
ERR0
ERR :
LD
LD
A,1
ERR0 :
(ECODE) f A
CALL
PSET ;ERASE CURSOR
LD
DE f (RETVA)
LD
HL 9 X1
LD
BC,PSIZE
LDIR
•
RET
RETVA:
DS
DS
2 ;RETURN VALUE ADD.
X0 :
2 ; BUFF.
Y0 :
DS
2 : BUFF.
DFMC :
DS
2 ;DEFAULT CURSOR
XI :
DS
2 ;X POSITION
Y1 :
DS
2 ;Y POSITION
BMASK :
DS
4 ;BUTTON CONDITION
MSDATA :
DS
3 ;MOUSE DATA
ECODE :
DS
1 ;ERROR CODE
MC :
DS
2 ;MOUSE CURSOR PAT ADD
MCCOL :
DS
1 ;MOUSE CURSOR COLOR
XL:
DS
2 ;X UNDER LIMIT
XR :
DS
2 ;X UPPER LIMIT
YU :
DS
2 ;Y UNDER LIMIT
YD :
DS
DS
2 ;Y UPPER LIMIT
MODE :
1 ;WIDTH AND WRITE PAT
MSIN :
LD
LD
BC.ZSIO+3
A f 5 - ; ->WR5
OUT
(C) f A ; WR5 SELECT
XOR
A
•
OUT
(C),A ;RTS High
1
LD
D.80H
MSINW :
DEC
D : WAIT
•
JR
NZ,MSINW
t
LD
A,5
OUT
(C) f A ; WR 5 SELECT
LD
A t 2
OUT (C) t A : RTS Low
E2DD11 D9
33CB20 EC
第 6 章 SIO 119
EBA4
EBA5
KBA6
EBA9
EBAC
EBAD
EBAE
EBB1
BBB3
EBB5
BBB7
EBB9
011FA2
3E 47
ED 79
3B 1A
ED 79
C9
EBBA
EBBD
BBC0
BBC2
EBC3
BBC4
EBC6
EBC7
011F93
21 EBCA
16 0F
7E
23
ED 79
15
20 F9
EBC9
C9
EBCA
EBCB
EBCD
18
01 00
02 70
EBCF
04 44
EB76
FD
2A EB80
EB7A
ID
EB7B
20
E9
EB7D
C3
EB14
EB80
EB82
01
1F93
EB85
21
0000
EB88
2B
EB89
7C
EB8A
B5
EB8B
28
0D
EB8D
AF
BB8E
ED
79
EB90
ED
78
EB92
IF
EB93
30
F3
EB95
0B
EB96
ED
78
EB9ft
EB99
B7
C9
EB9A
D5
EB9B
CD
EBA5
EB9E
D1
EB9F
2B
EBA0
7C
EBA1
B5
EBA2
20
EB60 IE 05
EB62 FD 22 EB80
EB66 16 0^
LD
E f 5 ;RETRY COUNT
LD
(IYBUFF),IY
MSRTRY :
LD
D,3 ;COUNT
MSINL :
CALL
MSGET
JR
LD
C f FAIL
(IYf0) f A
INC
IY
DEC
D
JR
NZ,MSINL
•
RET
FAIL :
LD
IY,(IYBUFF)
DEC
E
•
JR
NZ,MSRTRY
t
•
JP
ERR
IYBUFF :
DS
2
MSGET :
LD
LD
BC.ZSIO+3
HL f 0000H
MSGET0 :
DEC
HL
LD
A 9 H
OR
L
•
JR
Z f LATE
t
XOR
A
OUT
(C) f A ; RR0 SELECT
IN
A f (C)
RRA
; Bit0 ON?
•
JR
NC,MSGET0
•
DEC
IN
OR
BC ; BC=1F92H
A f (C) ;GET DATA
A ;RESET CARRY FLAG
•
RET
LATE :
PUSH
DE
CALL
SETMS
•
POP
DE
; HL=0000H
LATE0 :
DEC
HL
LD
A f H
OR
L
•
JR
NZ,LATE0
t
•
t
RET
SETMS :
DI
CALL
SBTCTC
CALL
SETSIO
El
••INITIALIZE
•
RET
SBTCTC :
LD
BC,ZCTC+2 ; CTC2=CHANNBL
LD
A f 010001 11B ;MODE
OUT
(C) t A
LD
A,26 ;TIME CONSTANT
OUT
(C) t A
•
RET
SETSIO :
LD
BC,ZSIO+3 ;CHANNEL B
LD
HL,SIODAT
LD
D,15 ;COUNT
SIOL :
LD
A f (HL)
INC
HL
OUT
(C) f A
DEC
D
•
JR
NZ f SIOL
t
•
RET
SIODAT :
DB
00011000 B
DB
1,00H
DB
2 t 70H
1 i/
A B
B B
EE
3 D D B 9
F c c F c
2 0
8
B 9 7 3 3
E 0 7 2 F
D 8 D D 5 0 9
c 3 F F 1 2 c
8 B D 0 2 3 5
6 6 6 7 7 7 7
B CQ 3 CQ bbcq
E E E E E E E
試験に出る XI
ED 53 EBF3
0F
0F
32 EBF7
CD EC6E
22 EBF5
6A
26 00
29
ED 5B EBF3
19
11 EBF3
01 0002
ED B0
PATD : DS
PATB : DS
COLOR: DS
XLOPWB : IN
XOR
OUT
INC
INC
DB
DB
DB
DB
5 f 00H
6 f 00H
7 f 00H
3 f 11000001B
EBD9
EBDD
EBE0
EBE4
EBE5
EBE6
EBE8
EBEC
EBEF
EBF2
EBF3
EBF5
EBF7
EBF8
EBFC
EBFD
EBFE
EC01
EC04
EC07
EC08
EC0A
EC0B
EC0F
KC10
EC13
KC16
EC30 2A EBF5
EC33 014000
EC36 09
BC37 D8
EC38 22 EBF5
KC3B 18 DB
EC45 C5
EC46 08
EC47 57
EC48 08
EC49 ED 78
EC4B AE
EC4C ED 79
EC4E 23
EC4F 03
EC 18 2A EBF3
EC1B ED 4B EBF5
EC1F 78
EC20 B6 C0
EC22 5F
EC23 57
EC24 E2 EC29
EC27 16 01
EC29 3A EBF7
BC2C A2
EC2D C4 EC3D
EBD1 05 00
EBD3 06 00
EBD5 07
EBD7 03 Cl
DADA30DAD9
E2E7B2E3CC
2 21
E83E 3979
70272 D5D
DEF 01234
33344444
cccccccc
EEEEEEEE
第 6 章 SIO 121
80=16t5
HL=5
10
20
40
80 ••HL=(HL/8) 拿 80
(WIDTH 40)
PATCH2
; 0R
ADD
ADD
ADD
ADD
ADD
ADD
ADD
NOP
HL
HL
HL
HL
HL
HL
HL
;DOWN
DEC
JP
LINE
POP
PUSH
NZ f XLOPWB
••SAME LINE GO ON
BC
HL
;BACK ADDR
: SAVE P-ADDR
PATCH 1
;OR
LD
ADD
LD
AND
CP
JF
LD
LD
ADD
LD
LD
A f 08H
A,B
B f A
0C0H
E
Z f DONEWB
;VECTOR DOWN
; BC=ADDR, ADD HIGH BYTE
••MASK 11000000
••CHECK IN?
;OK MASK
HL f 0C050H
HL,0C028H (WIDTH 40)
HL f BC
B 9 H
C f L
DONEWB :
POP
EXX
DEC
EXX
JP
NZ f YLOPWB
HET
;ADDK=4 ㈣ 0H+(Xl>>3>+<<Y1 & 7)<<
; ADDH=4000H^(BC/8) ♦((L AND 7)<
; HL=Y1 f BC=Xl.BREAKS HL.A.BC.DE
;return HL=addr,A^mask 9 D = count
<Yl>>3>*80
(HL/8) 拿 80
XYADDR : LD
CALL
LD
LD
DIV8
D f H
E 9 L
;SAVE L
; HL=HL/8
: DE = HL
EC50
EC51
15
C2 EC49
EC54
EC55
Cl
E5
EC56
EC58
EC59
EC5A
EC5C
EC5D
3E 08
80
47
E6 CO
BB
CA EC66
EC60
21 C050
EC63
EC64
EC65
09
44
4D
EC66
EC67
EC68
EC69
EC6A
El
D9
15
D9
C2 EC45
EC6D
EC6E
EC6F
EC72
EC73
7D
CD EC99
54
5D
EC74
EC75
EC76
EC77
EC78
EC79
EC7A
EC7B
EC7D
EC7E
EC7F
E6 07
87
87
87
EC80
EC82
EC83
C6 40
57
IE 00
EC85
BC86
EB
EC87
EC88
60
69
EC89
EC8A
EC8D
7D
CD EC99
19
EC8E
EC90
EC91
EC92
E6 07
47
57
3E 80
EC94
EC95
EC96
EC98
0F
10 FD
C9
122 试験に出る XI
L L E L L L L
H H D H H H H
HL has result (address},
D has mask count (0-7).
CB 3C
CB ID
CB 3C
CB ID
CB 3C
CB ID
C9
ECB6 ECD6
ECF6 ED16
ED36 ED56
ED80 EDAA
03 0A
FF FC 00
FF F0 00
FF C0 00
FF F0 00
FF FC 00
F3 FF 00
C0 FF C0
00 3F F0
00 OF C0
00 03 00
EC99
EC9B
EC9D
EC9F
ECA1
ECA3
ECA5
ECA6
ECAA
ECAE
ECB2
ECB6
ECB8
ECBB
ECBE
ECC1
BCC4
ECC7
ECCA
ECCD
ECD0
KCD3
ECD6
BCD8
ECDB
BCDE
ECE1
ECE4
ECE7
ECEA
ECED
ECF0
ECF3
ECF6
BCF8
ECFB
BCFB
ED01
BD04
ED07
ED0A
ED0D
ED10
ED13
ED16
ED18
ED1B
ED1E
ED21
ED24
ED27
ED2A
ED2D
ED30
ED33
ED36
ED38
ED3B
ED3E
ED41
ED44
ED47
ED4A
ED4D
ED50
ED53
ED56
ED58
ED5C
DIV8 : SRL
RR
SRL
RR
SRL
RR
RET
•
;DEFAULT MOUSE
ARW8 : DW
DW
DW
DW
參
ARW80 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
t
ARW81 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
t
ARW82 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
t
ARW83 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
ARW84 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
H
L
H
L
H
CURSOR
ARW80 f ARW81 ;BIT
ARW82.ARW83
ARW84 f ARW85
ARW86 f ARW87
3,10
0FFH f 0FCH f 000H
0FFH f 0F0H f 000H
0FFH f 0C0H f 000H
0FFH f 0F0H f 000H
0FFH f 0FCH f 000H
0F3H t 0FFH f 000H
0C0H f 0FFH f 0C0H
000H f 03FH f 0F0H
000H f 00FH f 0COH
000H f 003H t 000H
3,10
07FH f 0FEH t 000H
07FH f 0F8H f 000H
07FH f 0E0H f 000H
07FH f 0F8H f 000H
07FH f 0FEH f 000H
079H f 0FFH f 080H
060H f 07FH f 0E0H
000H f 01FH f 0F8H
000H f 007H f 0E0H
000H,001H f 080H
3,10
03FH f OFFH f 000H
03FH f 0FCH f 000H
03FH f 0F0H f 000H
03FH f 0FCH f 000H
03FH f 0FFH f 000H
03CH f 0FFH f 0C0H
030H f 03FH f 0F0H
000H f 00FH f 0FCH
000H f 003H f 0F0H
000H 9 000H 9 0C0H
3,10
01FH f 0FFH t 080H
01FH f OFEH^OOH
01FH f 0F8H f 000H
01FH f 0FEH t 000H
01FH f 0FFH f 080H
01BH f 07FH f 0E0H
018H f 01FH f 0F8H
000H t 007H f 0FEH
000H f 001H f 0F8H
000H f 000H f 060H
3,10
00FH f OFFH^COH
00FH f 0FFH f 000H
00FH f 0FCH f 000H
00FH f 0FFH f 000H
00FH f 0FFH f 0C0H
00FH f 03FH f 0F0H
00CH f 00FH f 0FCH
000H f 003H f 0FFH
000H f 000H f 0FCH
000H f 000H t 030H
SHIFTED PATTERN
0000000800
000008 EFE8
AB808EFFF71
0FFEFFF7100
3FFFFF 90000
07777776000
0000000 coo
00000 CFFFC
AFC0CFFFF30
0FFFFFF3000
3FFFFFC0000
03333333000
0000008 E80
80008 EFFF6
AFE8EFFF710
0FFFFF 71000
3FFFFFE8000
01111111000
000000 CFC0
C000CFFFF3
AFFCFFFF300
0FFFFF 30000
3FFFFFFC000
00000000000
04 0A
07 FF E0 00
07 FF 80 00
ARW85 : DB
DB
DB
4,10
007H f 0FFH f 0E0H f 000H
007H f 0FFH f 080H f 000H
第 6 章 SIO 123
KDK4 EDFA
ARW86 :
ARW87 :
ARW4 :
ARW40 :
ARW4 1:
ARW42 :
ARW43 :
ED60
ED64
ED68
ED6C
ED70
ED74
KD78
ED7C
ED80
ED82
ED86
ED8A
ED8E
ED92
ED96
ED9A
ED9E
EDA2
EDA6
EDAA
EDAC
EDB0
EDB4
EDB8
FDBC
EDC0
EDC4
EDC8
EDCC
EDD0
EDD4
HDD8
EDDC
EDE0
EDE4
BDE6
EDE8
EDEA
EDEC
KDKK
EDF0
EDF2
EDF4
BDF6
BDF8
EDFA
BDFC
BDFE
EE00
EE02
EE04
EE06
EE08
EE0A
EEOC
EE0E
EE 10
EE 12
EE 14
BE16
EE18
EE1A
EB1C
EE1E
EE20
EB22
EE24
EE26
EE28
EE2A
BB2C
EE2E
EE30
007H f 0FEH f 000H f 000H
007H f 0FFH f 080H f 000H
007H f 0FFH f 0E0H f 00OH
007H f 09FH f 0F8H f 0O0H
006H t 007H f 0FEH f 000H
000H f 001H f 0FFH f 080H
000H f 000H f 07EH f O00H
000H f 000H f 018H f 000H
4,10
003H f 0FFH,0F0H f 000H
003H f 0FFH f 0C0H f 000H
003H f 0FFH f 000H f 000H
003H f 0FFH f 0C0H f 000H
003H f 0FFH f 0F0H f 000H
003H f 0CFH f 0FCH f 000H
003H f 003H f 0FFH f 00OH
000H f 000H f 0FFH f 0C0H
000H f 000H f 03FH f 000H
000H t 000H f 00CH,000H
4.10
001H t 0FFH f 0F8H f 000H
001H f 0FFH f 0E0H f 000H
001H f 0FFH f 080H f 000H
001H f 0FFH f 0E0H f 000H
001H t 0FFH f 0F8H f 000H
001H f 0E7H f 0FEH f 000H
001H f 081H t 0FFH f 080H
000H t 0O0H f 07FH f 0E0H
000H, ㈣ 0H t 01FH,080H
000H f 000H # 006H f 000H
ARW40.ARW41 ;BIT SHIFTED PATTERN
ARW42,ARW43
ARW44 f ARW 45
ARW46 f ARW47
2.10
0FEH f 000H
0FCH f 000H
0F8H f 000H
0FCH f O00H
0FEH f 000H
0DFH f 000H
08FH f 080H
007H f 0C0H
003H f 080H
001H f 000H
2,10
07FH f 000H
07EH f 000H
07CH f 000H
07EH f 000H
07FH f 000H
06FH f 080H
047H f 0C0H
003H 9 0E0H
001H f 0C0H
000H t 080H
2,10
03FH t 080H
03FH f 000H
03EH 9 000H
03FH f 000H
03FH f 080H
037H f 0C0H
023H f 0E0H
001H f 0F0H
000H f 0B0H
000H,040H
2,10
01FH t 0C0H
01FH f 080H
01FH f 000H
01FH f 080H
01FH f 0C0H
0000000000
0000000000
00000 CFFFC
FC0CFFFF30
00000000
00000000
0008EFE8
08EFFF71
EFFF7100 A F
FFF 90000 0 F
77776000 43333333000
00000000 00000000000
FFFFF30O0
FFFFC0000
0000000000
0000008 E80
80008 EFFF6
FE8EFFF710
AFFFFF 71000
OFFFFFE80O0
4111111100 0
0 0 0 0 0 0 0 0 0 0 o
6 2 E
2 5 7
E E E
E E E
0 c 8
13 6
E E E
GEE
A 0000000000 A 0000000000 A 0000000000 A 0 0 0 0 0
00000008 C80 0000008 CEC8 0 8 0 0
0 8 c E F K 4 0C808C
2^C8CEFF731 2FECEFF7310 2FFEFF 73100 2FFFFF
0PFFFFD8000 07777764000 03333332000 0 11111
BBBBBBBB BBBBBBBBBBB BBBBBBBBBBB w WWW BBBBBBBBBBB BBBBBBBBBBB BBBBBBBBBBB B B B B 3 B
DDDDDDDD DDDDDDDDDDD DDDDDDDDDDD D DDD DDDDDDDDDDD DDDDDDDDDDD DDDDDDDDDDD DDDDDD
24 試験に出る XI
EA00
EA08
EA10
EA18
EA20
EA28
EA30
EA38
EA40
EA48
EA50
EA58
EA60
EA68
EA70
E3
E3
A6
B5
3B
9E
18
FB
37
71
EB
2F
D6
B9
38
リスト 6-3 マウスドライバ(リスト 6-2) のダンプリスト,もしくは
• MOUSE.OBJ •でセーブしてねとあの子が曾った
SUM
EE32
IB
E0
BE34
11
F0
EE36
00
F8
EE38
00
70
EE3A
00
20
EE3C
02
0A
EE3E
0F
E0
EE40
0F
C0
EE42
0F
80
EE44
0F
C0
EE46
0F
E0
EE48
0D
F0
EE4A
08
F8
EE4C
00
7C
EE4E
00
38
EK50
00
10
EE52
02
0A
EE54
07
F0
EE56
07
E0
EE58
07
C0
EE5A
07
E0
EE5C
07
F0
EE5E
06
F8
BE60
04
7C
EE62
00
3E
EE64
00
1C
EE66
00
08
EE68
02
0A
EE6A
03
F8
EE6C
03
F0
EE6E
03
E0
EK70
03
F0
EE72
03
F8
EB74
03
7C
BE76
02
3E
EE78
00
IF
BE7A
00
0E
EE7C
00
04
EE7E
03
0A
EE80
01
FC 00
EE83
01
F8 00
EE86
01
F0 00
EE89
01
F8 00
EE8C
01
FC 00
BE8F
01
BE 00
EE92
01
IF 00
EE95
00
0F 80
EE98
00
07 00
EE9B
00
02 00
DB
DB
DB
DB
DB
ARW44 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
§
ARW45 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
ARW46 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
ARW47 : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
END
01BH t 0E0H
011H f 0F0H
000H f 0F8H
000H f 070H
000H.020H
2,10
00FH f 0E0H
00FH f 0C0H
00FH f 080H
00FH f 0C0H
00FH f 0B0H
00DH f 0F0H
008H f 0F8H
000H f 07CH
000H f 038H
000H.010H
2,10
007H f 0F0H
007H f 0E0H
007H f 0C0H
007H f 0E0H
007H t 0F0H
006H,0F8H
004H f 07CH
000H f 03EH
000H f 01CH
000H t 008H
2,10
003H f 0F8H
003H f 0F0H
003H f 0E0H
003H f 0F0H
003H f 0F8H
003H f 07CH
002H f 03EH
000H f 01FH
000H t 00EH
000H 9 004H
3,10
001H f 0FCH f 000H
001H f 0F8H f 000H
001H f 0F0H t 000H
001H t OF8H f 000H
001H f 0FCH f 000H
001H f 0BEH f 000H
001H f 01FH f 000H
000H f 00FH f 080H
000H f 007H f 000H
000H f 002H f 000H
B021B18FBAA6D99
EB32E612E2E1F34
9D9A82E29BC3BAD
2E2E4332DEDCE3C
20ECA8CDDBD29BB
203A32EEC2C0DEE
B8C2BEA442BED99
E1E3E37D02E3C43
6118F 7210 BD5BD1
506224323 E20EC2
3B2E270AF1285BD
2E 33210 E0322AEF
E10CC8EC8AB3D95
535EE33A72E0C3F
B1EA6FC2B936B1B
E137A0E3EC3EE2E
FD6CF 665455 72
04B 06095 CC5
. o
EAA9AADE68D s
B 331022 A03C
ft,
41ABDB288FB
023BCC22 3 0 E 6
5 ¢
6981B493FB3 5
0FD3E0100E3
308AB8BE112
012232 EFF32
6B6BAB3AB2B
EEBE3B3EE2E
B13AB1AC9BD
E120E02DDE2
9AEDBBBDDBA
3C7C231CC22
A3BB2BBB5A6
32EE2ECEF20
ED00
ED08
ED10
HD18
ED20
ED28
ED30
ED38
ED40
ED48
ED50
ED58
ED60
ED68
ED70
ED78
SUM :
ED80
ED88
ED90
ED98
EDA0
EDA8
KDBO
EDB8
EDC0
EDC8
EDD0
EDD8
EDE0
EDE8
EDF0
EDF8
SUM :
EE00
EE08
EE 10
EE18
EE20
EE28
EE30
EE38
EE40
EE48
EE50
EE58
EE60
EE68
EE70
EE78
SUM : 43 90 F8 El B4 29 2D 0A
SUM : BD E9 D5 77 B9 E614IE
SUM : B8 30 9F 3F 08 C51C 87 0616
SUM :
EB00
EB08
EB10
EB18
EB20
EB28
EB30
EB38
EB40
EB48
EB50
EB58
EB60
EB68
EB70
EB78
ECA0 ID
ECA8 D6
ECB0 56
ECB8 FF
ECCO 00
ECC8 FF
ECD0 00
ECD8 7F
ECE0 00
ECE8 FF
ECF0 00
ECF8 3F
CB 3C CB
EC F6 EC
ED 80 ED
FC 00 FF
FF F0 00
00 C0 FF
0F C0 00
FE 00 7F
7F F8 00
80 60 7F
07 E0 00
FF 00 3F
ID C9 B6
16 ED 36
AA ED 03
F0 00 FF
FF FC 00
C0 00 3F
03 00 03
F8 00 7F
7F FE 00
E0 00 IF
0180 03
FC 00 3F
EC
77
ED
CA
0A
54
C0
A9
F3
DD
F0
AD
0A
DF
E0
53
79
6D
F8
55
0A
75
F0
A8
SUM : 92 EE 18 64
EC80 C6 40 57IE
EC88 69 7D CD 99
EC90 47 57 3E 80
EC98 C9 CB 3C CB
126 試験に出る XI
CB 3B B5 4C 15F3
00 19 EB 60 : DF
EC 19 E6 07 : 3E
C8 0F 10 FD : 40
ID CB 3C CB : 8A
EAD8 D9 EB 18 92 AF ED 5B 44 : A9
EAE0 EB 2A 2D EB B7 ED 52 38 : 5B
EAE8 09 ED 5B 2D EB 2A 46 EB : C4
EAF0 ED 5217 ED 5B 40 EB 2A : F3
EAF8 2B EB B7 ED 52 38 09 ED : 3A
CCA8EEACFFA 00000
3F0F1F0F0F 000080
0F3F073F 034008 F8
00018000 C0088FF1
F000F000F00FFF10
F0C0F060P03FF900
F00EF80FFC 077700
3F0F1F0F0F 000000
0F0F0F0F0F 000000
0301010000000000
C000E880FCC000EE
F3F8F1FCF0FE0EF7
F03FF01FF00FEF70
3C0F1E0F0F0FFF00
0F0F0F0F0F 077760
0F 01070003000000
A9086C 83738 C9D97
61B71ED2500EDC28
BBDBCD9883E61D97
EEEEE 3000236 E 718
5305940 E595AD997
FF0F2C47C7EC4C28
2B2B220B9D1B4C97
2504EA0DDECB4E20
CD1D7B187
EE0E5E015
E c 0 9 5 D 6
A E c 0 4 5 E
EE0E5E015AEC045E
E9BBF7BB 98960249
62EE5FEED74ECC52
D0330A553D2709C9
C0FFC3FF2EC45DE2
B61A61A2E 8501599
E 212 E 02270182192
0808080808080808
0011223344556677
cccccccccccccccc
EEEEEEEEEEEEEEEE
5 6 7 E 3 4 F
D A 1 A 8 c 4
B119D1 315
c 6555 c 906
098BE2DB043B4D07
0772AAEE200E0C0F
0DD1D1AA 50030 B22
0EEDC01C17032EC3
1FBB39E1927A3F8F
2A0EFC 327002 B350
FD359B9FD00BAAEF
10FACF71E00E73F0
380DBBD 33161 BBDB
923CFEE 92003 EE3E
15F50A71E80BDF93
0B1D2B 40710432 CF
5C895DE9F95DBBB3
E77CBC3C0C0E55E5
CBD7CBF96941DD8D
12EB7E171F4CEEFE
0808080808080808
8899AABBCCDDEEFF
B CPB3 BBBBB noBBB 3 B 3
EEEEEEEEEEEEEEEE
2441E2087EECCE8A
0C80F16DEFB7CE30
FFF 0000000 DE0000
FFC 0000088 EE0080
33300808 FFA2EE3E
0000OF8FF1F5FF07
00000 FFF10DEA000
000OOFFF80EE00C0
000FF111104C2C7F
F0FF 300000 E30F07
FFF30A 00000 EE00A
FFF 000000 E0EE080
33330400 EF66E8F2
000000 EEF7027F80
AO000OFF700EE000
0000C0FFE00EE000
400CFC11 10008 CF1
0CCFF 00000016 FD0
8B88DC3BC1A32DDE
624F13D81BFAEDA3
0 0 0 0 A, 0 8 0 0 8 0 00 8 0 E A
880E08FEE3EF0E30
F0E32F0FF 0760323
6032010000000000
0000000 A0C00C0C4
0C0C40F0C7FF1F70
F1F70F12F 0770330
7033011000000000
0000000008 A0E88E
0E88E8E28F0E3FF0
E3FF0FB0F 827033 0
7033011000000000
00A 000000000 CA0F
0C00FCC7CF1C70F1
C72F1FF0FD 074230
7 4 0 oo 0 11 0 0 0 0 0 0 0 0
59029367
B2CDD96E
B8ACB4B6
E 4368889
E E F 8 9
7 8 8 9 6
CCEE 78454 AD
A29CAF48FCF
71F83D278ADF6F83
043DF 77869 D4CE35
25CB 032679 D930AB
513EBA3E87F7002E
D029D6FECD0D67D4
ED32EE133E2B17F1
B71B0C2FA552BD93
E 005003 BE010EFCC
20ED8CA2AE0E 0939
403E1FC 2338380 FE
A62B1D804F 692800
210 E0C 7801172322
BF89B 706939 DDB5D
E51DE380A97EFE11
B9FD1F6E41D5523B
2CAC31E3C0E0082E
B 7
51
7 9 B 19 7
1 c E 2 c 4
E0EFEEDD0
B13A31CF8
_ ■ •• m
• •• _
• m
m mm w m
_ mam mm m
b • mm m
_
EE90
BE
00
01
IF
00
00
0F
80
: 6D
SUM :
6F
BF
5F
DE
4B
62
24
62
B9D0
EE98
00
07
00
00
02
00
: 09
EE80
01
FC
00
01
F8
00
01
F0
: E 7
SUM :
_ m
BF
• _
04
» m
F9
_ mm m
20
_ mam mm m
FB
_ mm mm «
FC
_ mm
10
■ _
71
39E5.
EE88
00
01
F8
00
01
FC
00
01
: F7
リスト 6-4 マウスが舞うす,もしくは早くパターンエディタになりたい
100
CLEAR &HE000
110
IF MEM$(&HEA00 f 4)<>HEXCHR$( M EB 5E
23
56" > THEN LOADM "MOUSE.OBJ ,f
120
DEFUSR0=AHEA00
130
X=100 : Y=100
140
MEM$(&HE000 f 4)=MKI$(X)+MKI$(Y)
: *X Y
150
f MEM$(&HE000 f 4)=HEXCHR$( M 64 00 64
00 #l
)
: f X Y
160
MEM$ ( &HE004 t 4 ) =HEXCHR$ ( f, 01 02 03 04 M )
: , BUTTON
CONDITION
170
MEM$(«tHE008 f 4 )=HEXCHR$( l# 00 00 00 00 tf )
: 1 MOUSE DATA
180
MEM$ (&HB00C f 3 ) =HEXCHR$ ( f# 00 00 04 11 )
: 1 MOUSE CURSOR
190
X0=40 : X1=240 : Y0=24 : Yl=160
200
MEM$(&HE00F f 8)=MKI$(X0)^MKI$(Xl-l)
♦HKI*(Y0)+MKI$(Y1-1)
210
, MEM$(&HE00F f 8)=HEXCHR$( M 28 00 EF
00
18 00
9F 00 ff ) : 1 AREA
220
MEM$(&HE017 t 1)=HEXCHR$( tf 00 ,# )
: f MODB
230
WIDTH40
240
i
250
»MEM$<&HE00C,3) =HEXCHR$( M 80 D0 07
,# ):
•トスルト
CURSOR 力 • 1 . 1
ニナル
260
, MEM$UHE080,16>=HEXCHR$《"90 D0 93
D0
96 D0
99 D0 9C D0 9F
D0 A2
D0
A5
D0 M )
270
f MEM$(&HE090 f 16 ) =HEXCHR$ ( ff 0 1 0180
01
0140
01 0120 01 01
10 01
01
08
01 M )
280
f MEM$(&HE0A0 f 16)=HEXCHR$( M 01 04 01
01
02 01
01 01”>
290
CLS 4 : INIT
300
LINE(X0-1 f Y0-l)-(X1 f Yl) f PSET f 7 f B
310
LINE((X0-1)/8 f (Y0-1)/8)-((Xl-8)/8 f
(Y1
-8)/8)
,CHR$(225),BF
320
i
330
D$=USR0(CHR$(&H0 9 &HE0))
340
•
350
BT=PEEK(&HE008) AND 3
360
IF BT=3 THEN WIDTH80:BND
370
IF BT=1 THEN C=224:GOSUB "PSET"
380
IF BT=2 THEN C=225:GOSUB "PSET”
390
GOTO 330
400
9
410
LABBL W PSBT M
420
X=CVI(MEM$(&HE000 f 2)) : X=INT(X/8)
430
Y=CVI(MEM$(&HE002 f 2)) : Y=INT(Y/8)
440
PSBT(X4239^1 t Y4l59fl f (225-C)t7)
450
LOCATEX f Y : PRINTCHRS(C); : RETURN
打ち込んだなら,
SAVEM '' MOUSE . OBJ ",& HEA 00, & HEE 9 D
でセーブしていただきたい(テープでも可だけど,はっきり言ってマウスより先にディス
クを買うべきである)。次にリスト 6-4 を RUN する(おっと , turbo BASIC の場合は事前
に 「KMODE 0」を実行しておくこと)。するとディスクが回り, ^ MOUSE . OBJ " が口
ー ドされた後,何やらパターンエディタもどきの画面になるであろう。セコイことにモノ
クロで,気分の良いことにセーブ機能などは一切付いていない。なぜならばこのブログ
ラムは,私が苦心してデザインしたマウスカーソル(本当はただの左上向きの矢印だけど)
が,画面を華麗に舞う姿を楽しむためだけ,のものだからである。左側のボタンを押すと
白丸が,右側のボタンを押すと中抜き丸が表示されるであろう。終わりたいときは両方の
ボタンを同時に押すのであるが,人間の指はどうしても左右のボタンを押すのに時間差を
生じてしまうらしく,なかなかに難しいはずである。いざとなったら , [SHIFT 14-
BREAK 丨 をちょんと押した後,どちらか片方のボタンで BREAK する。
まずはリスト 6-4 の説明,すなわちリスト 6-3 の機械語ルーチンの使い方である。
140〜220行はパラメータの指定である。中身は,
第6章 SIO 127
① マウスカーソルの 位置 ( X , Y の 順)
2 バイトの値で指定する。 MKI $ の使い方に注意。合計 4 バイトである。
② どのボタンカヾ押されたらリターンするか
これは 4 とおり指定できる。
00 H = ボタンが押されてなかったら RET
01 H =左側ボタンだけが押されたら RET
02 H = 右側ボタンだけが押されたら RET
03„ =両側とも押されたら RET
04„ =無効
リスト 6-4 では,とにかく何かボタンが押されたら RET するように 01 H , 02„, 03 H の 3 と
おりを指定している。 04 H は「詰め物」のよ一なものである。合計 4 バイト。
③ マウスデータ
最初の 3 バイトには,最後にマウスから読み出された生のデータが入つている。 4 バイ
卜目は エラーコードで ある。
00„—正常
01 H — マウスがつながっていないなど
02„—マウスカーソルの位置が,最初からウインドウの外側にある0
合計4バイト。
④ マウスカーソルの 形状,色の指定
最初の2バイトはカーソル用のグラフィックのデータが格納されているアドレスであ
る。000 0 H を指定すると,デフォルトの左上向き矢印になる0 3バイト目は色の指定。リス
卜 6-4 では緑になっている。合計3バイト0
⑤ ウィンドウ (移動範囲) の 指定
X 方向の下限値, X 方向の上限値, Y 方向の下限値, Y 方向の上限値,の順に指定す
る。それぞれ2バイトの値である。リスト5では,マウスカーソルの左上端の位置が,
(40, 24) — (240 — 1,160— 1) の囲いの中から出ないようにしている。合計8バイト。
⑧ モードの指定
第0ビットは WIDTH の指定。0なら40字モード,1なら80字モードとなる。第1ビッ
卜はマウス動作をするか,ただのグラフィック描画をするかのフラグである0 〇ならマウ
ス動作,1なら④で指定されたマウスカーソルを XOR モードで表示するだけですぐ RET
❻
のパラメー
する。合計1バイト。
ま,大体以上なわけである。よって,正しいリスト 6-3 の使い方は,
夕を指定して,330行のようにそのパラメータの先頭番地をもって, USR 命令である。そ
の後,ボタンの状態を知りたいのなら③の先頭1バイト(リスト 6-4 では E 008 H 番地)を
PEEK して AND 3,マウスカーソルの位置を知りたいなら,420行,430行のようにすれ
ばよい。その後8で割っているのはキャラクタの位置に変換しているのだから勘違いはし
ないように。
それではたちまちリスト 6-2 の説明に入る。最初の EA 0 F H まではパラメータの転送など
128 試験に出る XI
である。扱いやすいように EB 31 H からの24バイトに転送して使うのである (RE 丁すると
きには,元に転送し直す)。
次から EA 41 H までは, 40/80 字モードの 切り換えで, ブログラムを 直接書き換え るという
最低のテクニックを使っている。パラメータの⑧の第 i ビットが 1 ならば, £ A 45 H 番地に来
てたちまち RET , さもなくば EA 49 H からのマウスドライバに入る。
後は詳しい説明はしないで,サブルーチンの説明にとどめておく。
CIN = EADC H は, ( X 0, Y 0) がウインドウの中に入っているかどうかの判定 ルーチ
ン〇ウィンドウの中に入っていなければ A レジスタのビットを立てる(ビット1は Y ビ
ット〇は X )。
XSIGN = EB 0 A H は8ビットの符号付きの E レジスタを16ビット値にして DE レジス
夕に入れるもの。
MSIN = EB 49 h はマウスからの入力
SETMS = EBA 5 H はマウスのイニシャライズ
PAT = EBF 8 h はマウスカーソルの描画
XYADDR = EC 6 E „ は座標( X , Y ) から G - RAM のアドレスを計算するルーチン
そして, ECA 6„ 以降はグラフィックデータである。グラフィックデータは描画をスムー
スにするため,あらかじめ1ビットずつシフトしたデータを8とおり用意しておく方法を
採っている。メモリをけちって,実行時にいちいちシフトさせるとマウスの操作性がガク
ンと落ちるのである0 40字モードと80字モードの2とおりのデータで500バイト近くあ
る。清く正しいブログラムでは,起動直前にシフトしたデータを作るべきなのであるが,
しっかり手抜きを しているわけである。
では,「マウスを生かすも殺すもソフトしだい」とつぶやきつつ,この章を終わるのであ
る。
第6章 SIO 129
通信だってするのである
■第 7 章
1通信だってするのである
この章では前章の舌の根も乾かぬうちに通信をするのである。具体的には CZ -8 BM 2
( RS -232 C •マウスボード)用のコントロールブログラムなのである。ブログラムは turbo
BASIC の RS -232 C 関係の命令と同等のことができるようにすることを目的として作っ
た。よって turbo ユーザーにとっては,基本的にお呼びでない。しかしブログラム中の
SIO , CTC のアドレスをずらし,さらに CZ -8 FB 01 を使うか(もしくは CZ -8 FB 02 であっ
ても割り込みべクトルのつじつまを合わせる)すれば turbo でも使えることは使えるか
ら, 「 BASIC に依存しない通信ブログラム」を作る際の参考ぐらいにはなるであろう。
で,実は CZ -8 BM 2 にはカセットに入ったアプリケーションブログラム (機械語) が付
いてくるのであるが,どうやらこの章のブログラムはそれよりはましなものになったよう
である。
ところで通信であるが,私の持論では 「通信=不毛」 ということになっている。誰が
何と言っても現時点では (1987 年である) NTT が儲かるだけなのだ。モデムに必要なモ
ジュラ ー ジャックを取り付ける工事だけで何千円もボるそうな(資格のない人が取り付け
るのは禁止されている)。また,日本ではぼちぼちと通信速度が1200 bps , さらにはそれ以
上へと移行しつっあるようだが,はっきり言ってそれでもまだタコなのである。そして 一
番の問題は「パソコン通信なんかやってて何が面白いの?」である。おそらく面白いのは
CHAT だけであろう。後は PDS (パブリックドメインソフト)が手に入るなどというメリ
ットもあるが,よ一するに現状のパソコン通信は「それだけのもの」なのである。
もう少し言わせてもらうと, 私は CHAT が嫌いである。 やってみれば楽しいのだろ
うが,それでも嫌いである。なぜかと言うと,文明社会の「ユガミ」みたいなものを感じ
てしまうからなのだ。これはあくまでも想像するだけなのだが, CHAT の情熱の嵐に巻き
込まれたら最後なのではないだろうか。すなわち CHAT に命をかけているよ一な人は,他
人とのコミュニケーションにどっかこっか問題があるのではないかと思えるのである。面
と向かって肉声で話すよりも,キーボードをパコパコ叩いて文字で話す方がいいなんて,
なんか不自然だろう。
というわけで,この章のブログラムは,できればメディアコンバートなどに使い, くれ
ぐれもバソコン通信などには使わないよ一にお願いしたい。
衿れてはいきなり始《3
XI のユーザーは turbo BASIC のマニュアルを持っていないわけだから,表 7-1 (tur
boZ のマニュアルから引用)を参考にしていただきたい 0 ただしブログラムは BASIC のコ
132 試験に出る XI
マンドを拡張するわけではないので, USRO 〜 USR 9 を使うことになっている。その際,文
字列変数を渡すときには「その長さ」にちょいと気を付けなければいけないので,サンプ
ルプログラムをよく見て使うように。なお, SAVE , SAVEM , LOAD , LOADM はない
ので,自分で ( BASIC などで)プログラムを組むなどして解決するよ一に。
表 7-1 通信パラメータの脱明
通信バラメータには次のものがある,
1 ) ボーレート
2 ) パリティ
3 ) データビット長
4) ストップビット長
5) 通信制御指定
6 ) カナの表現方法指定
7 ) CR . LF コードの送信処理
8 ) CR . LF コードの受信処理
9) 日本語文字列の表現方:去指定(本書のフログ
ラムではしか使えない)
10) エンドコード指定
1 ) ボーレート
0~6の数値によりボーレートを指定する
数値
0
1
2
3
4
—— —
5
6
ボーレート
(bps )
150
300
600
1200
2400
4800
9600
■一 ■ ■■■ ■ <
2) 〆 、•リテイ
E :偶数パリティチ I ックを使用する。
0 :奇数パリティチヱックを使用する。
N :パリティチェックを使用しない。
3) データビット長
5 :データビット長を5ビットとする。
6 :データビット長を6ビットとする。
7 :データビット長を7ビットとする。
8 :データビット長を8ビットとする。
4) ストップビット畏
1:ストップビット長を1ビットとする。
2 :ストップビット長を 1.5 ビットとする。
3 :ストップビット長を2ビットとする。
5) 通信制御指定
X : XON XOFF コードによる制御を行なう。
R : RTS 制御信号の ON / OFF による制御をする。
N または省略:通信制御を行なわない。
この通信制御とは,データ送受信時に受信側に
おいてデータの受信処理が間に合わないとき,送
信側に対して送信の一時停止を要求し受信できる
状態になると送信再開を要求する方法のことをい
0 〇
♦ X •を指定すると,データとして X 0 FF コード
(& H 13) を送信側へ送ることによって送信の一時
停止を要求し, X 0 N コード (& H 11) により送信再
開を要求する。
♦ fT を指定すると, RTS 信号線を OFF にするこ
とによつて送信の一時停止を要求し, ON にするこ
とによリ送信再開を要求する。
6) カナの表現方法指定
S :データビット長7ビットでカナの送受信が
できる。
N または省略:データビット長7ビットでカナ
の送受信ができない。
データビット長7ビットでのカナの送受信はシ
フトインコード SK & H 0 F ) があると,それ以降の
データをカナとして処理し.シフトアウトコード
SO (& HOE ) があればそれ以降のデータを英数字と
して処理する。
7) CR , LF コードの送信処理
C :復帰改行コードとして CR コード (& H 0 D )
を送信する,
L または省略:復帰改行コードとして CR コー
ド (& H 0 D )+ LF コード (& H 0 A ) を送イ S する。
8) CR , LF コードの受信処理
C : CR コード (& H 0 D ) の受信によって復帰+改
行処理する。
L または省略: CR コード (& H 0 D ) のみを受信す
るとそれはデータとして処理される。 CR コード
(& H 0 D ) + LF コード (& H 0 A ) を連統して受信す
ると,復帰+改行処理をする。
9) 日本語文字列の表現方法指定
J : JIS 漢字コードを使用する“興字インコード
KK & H 1 B 4 B ) で日本語文字列の始まりを示し,
漢字アウトコード K 0(& H 1 B 48) で日本語文字列
の終わりを示す。
N または省略:シフト JIS 漢字コードを使用する。
(本害のブログラムでは ffsT しか使えない)
10) エンドコード指定
データ転送の終了を判断するためのエンドコー
ドを指定する。エンドコードとしてコントロール
コード (& H 00 〜 & H 1 F ) の中から任意の 一つを 選択
できる。実際に指定するパラメータは.キャラク
ターコード & H 40 〜 & H 5 F に対応する文字を使用
する (& H 60 〜 & H 7 F も可)。たとえば, D (または d )
と指定するとエンドコードとしてコントロール D
(& H 04) が使用される。またこのパラメータを省
略すると,エンドコードの送受信処理は行なわな
い 0
〔注〕
•通信パラメータのうちボーレート,パリティ,
データ長,ストップビット長は省略できないが,
それ以降のバラメータは省略できる。ただし,
途中のバラメータを省略して次のパラメータを
指定することはできない。
♦漢字の送受信はデータ長8ビットのときに可能
(シフト JIS コードを使うことになる)。また,力
タカナの送受信は SI / S 0 コードを使うことによ
ってデータ長が7ビットのときでも可能となる
(カナの表現方法指定が S であれば自動的に力
ナに変換する)。
第7章通 fS 133
各 USRW 数について
USR 5 : PRINT 文字列 + CR (+ LF ) を出力
USR 0 : OPEN オーブンする(パラメータ
する
先頭に0,1 , C のいずれかを
USR 6 : L 0 C バッファ 内のデータ数を返
付加すること)
す
USR 1 : CLOSE クローズする
USR 7 : EOF エンドコードを入力したか
USR 2 : LINPUT 1行入力する ( CR もしくは
どうかを返す
CR + LF まで)
USR 8 : PGETC 1 生データを1文字入力する
USR 3 : INPUTN N 個の文字を入力する
(カナの処理などはしない)
(個数は引数の文字列の先頭
USR 9 : PPUTC 1 生データを1文字出力する
の ASCII コード)
(カナの処理などはしない)
USR 4 : PRINTS 文字列を出力する
注) USR 2, USR 3 は,返す文字列の先頭の ASCII
コードで入力されたデータ数を示す。
そして リスト 7-1 = ソースリスト, リスト 7-2 =ダンプリスト(打ち込み確認には付録
A を参照のこと), リスト 7-3 =サンプルブログラム, リスト 7-4 =簡単なターミナルソフ
卜である(ただし使いものにはならないので,あくまでサンブルにすぎない)。リスト 7-1
の最初の方を見ると分かるだろうが, Z 80 SIO , CTC のアドレスがそれぞれ 1 F 98„ と
1 FA 8„ となつている。これは CZ -8 BM 2 のアドレス設定スイツチが,工場出荷時の2 - 3側
になつている場合のものである。スイツチが 1-2 側もしくは turbo の場合には,それぞれ
1 F 90„, 1 FA 0„ とすればよい。後は説明しても空しいのでやめておく。
リスト 7-1 通信 プログラムのソースリスト
.Z80
•
.PHASE
0EA00H
0330
QBREAK
BQU
0330H
1FCA
BBREAK
•
EQU
1FCAH
1F98
ZSI0
EQU
1F98H
;IF NOT,1F98H
1FA8
ZCTC
•
EQU
1FA8H
;IF NOT,1FA8H
005C
INTRSV
EQU
5GH
;INT VECTOR
0040
QMAX
EQU
64
;QUE SIZE
0080
QMAXX
•
EQU
QMAX+64
;Q SIZE+ALPHA
000D
CR
EQU
0DH
000A
LF
EQU
0AH
000E
SO
EQU
0EH
000F
SI
EQU
0FH
0011
XON
EQU
11H
0013
XOFF
EQU
13H
••CTRL CODES
;BAU RATE
0-6
;PARITY
E , 0,N
;DATA BIT LEN
5 t 6 f 7 f 8
;STOP BIT LEN
1,2,3
; C0NTR0LE
X , R,N ••け
>
;KANA MODE
S , N •"”
; CR f LF
SEND
C f L t lf ff
; CR f LF
RECEIVE
C,L,"”
••KANJI
J • N • •• M
;DUMMY
••END CODE
•
• @リノ
;PARAMS
;JUMP TABLE
EA00 C3 EA1E
JP
OPEN
••1,0 or
C ♦ PARAMETER
EA03 C3 EB84
JP
CLOSE
;+3
;TX BNDCODE
•
EA06 C3 ECDD
•
jp
LINPUT
;+6
;UNTIL
CR (♦LF)
EA09 C3 ED35
JP
INPUTN
;+9
;INPUT
n CHAR
134 試験に出る XI
EA0C
C3
ED68
JP
PRINTS
; + 12
;TX STRING
EA0F
C3
ED56
JP
PRINT
け 15
;TX STRING ♦
•
CR (*fLF)
EA12
C3
EB98
t
JP
LOC
••♦18
;RETURN BUFF
SIZE
EA15
C3
EBB9
JP
EOF
;+21
••EOF OR NOT
#
EA18
C3
EC9A
' jp
PGETCl
••♦24
;RIMITIVE GET
CHAR
EA1B
C3
ED90
JP
FPUTC1
••♦27
;PRIMITIVE PUT CHAR
•
EA1E
3A
EE60
OPEN : LD
A.(OPKNF)
EA21
B7
OR
A
EA22
28
07
JR
Z,OPENGO
EA53
EA56
EA57
EA59
EA5C
EA5E
EA61
EA62
EA63
32 EE4B
78
D6 04
DA EE26
FE 07
D2 EE26
4F
7E
23
OPENOK: LD (IOC) f A ; I f O or C
LD
A f B
;GET COUNT
SUB
4
JP
C f ERR
CP
7
JP
NC f ERR
LD
C f A
••COUNTER
LD
A f (HL)
INC
HL
EA64
EA66
EA68
EA6B
EA6D
EA6F
EA70
EA72
EA73
EA74
EA76
EA78
EA79
D6 30
FE 07
D2 EE26
16 D0
D6 02
F5
30 01
AF
B7
28 05
CB 3A
3D
18 F8
;BAU RATE
SUB
CP
JP
LD
SUB
PUSH
JR
XOR
OPEN0 : OR
0-6
f 0 f
: OR
JR
SRL
DEC
JR
NC f ERR
D f 208
2
AF
NC f OPEN0
A
A
Z f OPENl
D ; D=D/2
A
OPEN0
EA7B
EA7C
7A
32 EE2E
OPEN1 :
LD
LD
A,D
(CTR) f A
第 7 章通 信 7J5
EA8C
EA8D
EA8E
EA90
EA92
EA94
EA95
EA97
EA99
EA9A
EA9C
EA9F
EAA0
EAA1
EAE9
EAEA
EAA2
EAA3
EAA4
EAA6
EAA9
EAAB
7E
23
D6 35
DA EE26
FE 04
D2 EE26
EAAE
EAAF
EAB1
EAB2
EAB4
EAB6
EAB7
F5
16 E0
B7
28 05
CB 22
3D
20 FB
EAB9
EABA
EABB
EABE
BABF
EAC0
EAC3
EAC5
EAC6
EAC7
EAC9
EACC
EACD
EACF
EAD1
EAD3
7A
2F
32 EE61
FI
B7
EA EAC5
BE 03
0F
0F
F6 01
32 EE5A
OF
F6 80 #
F6 02
F6 08
32 EE54
EAD6
EAD7
EAD8
EADA
EADD
EADF
EAE2
EAE3
EAE4
EAE5
EAE6
7E
23
D6 31
DA EE26
FE 03
D2 EE26
3C
87
87
B3
32 EE52
EA7F FI
EA80 16 40
EA82 30 07
EA84 16 80
EA86 3C
EA87 28 02
EA89 16 C0
EA8B 5A
FOP
AF
LD
D f 40H
; 拿 16
JR
LD
INC
JR
LD
NC f OPEN2
D t 80H
A
Z.OPEN2
•• 拿 32
•
D.0C0H
; 拿 64
0PEN2 :
LD
E,D
;KEEP
;• PARITY
LD
E.O.N
A f (HL)
INC
HL
LD
D f 0
CP
f N f
JR
Z f OPEN3
INC
D
; D=1
CP
JR
f O f
Z,OPEN3
INC
D
;D = 2
CP
9 E $
JP
NZ f ERR
OPEN3 :
LD
A f E
OR
D
•
LD
B,A
;KEEP
;DETA BIT LEN
5,6,7,8
LD
A f (HL)
INC
HL
SUB
f 5 f
JP
C t ERR
CP
4
JP
NC f ERR
; A=0-3
PUSH
AF
LD
D f 11100000 B
OR
A
JR
Z f OPEN35
MLOOP:
SLA
D
DEC
A
•
JR
NZ t MLOOP
OPEN35 :
LD
A,D
CPL
LD
(MASK),A
POP
AF
OR
JP
A
PE f OFEN4
XOR
1IB
0PEN4 :
RRCA
RRCA
OR
LD
1
(WR3+1>•A
;RCV
RRCA
OR
80H
OR
02H
•
OR
LD
08H
<WR5+1>,A
;SND
t
;STOP BIT LEN
1,2,3
LD
A f (HL)
INC
HL
SUB
M 1
JP
C f ERR
CP
3
JP
NC f ERR
INC
A
ADD
A f A
ADD
A f A ; A=A<<2
•
OR
LD
E
(WR4+1>,A
: CONTROLE
X,R.N,""
;KANA MODE
S • N • •• ••
CR f LF
SEND
CR t LF
RECEIVE
C,L •”㈣
KANJI
J f N f M #f ; DUMMY
: END CODE
- 1 1
PUSH
PUSH
o E B F 6 5 E
0 4 0 4 0 4 E
E36E84E8
721F21F2
4 E 2 B 2 F
1 F c 7 B 5
5 5
c E
試験に出る XI
EAEB
21
EE3F
LD
HL.PDFLT
EAEE
11
EE45
LD
DE f PARAM
EAF1
01
0006
LD
BC f 6
EAF4
ED
B0
LDIR
;COPY DEFAULT
EAF6
EB
EX
DE t HL ; DE f =PARAM
EAF7
D9
EXX
EAF8
EAF9
El
Cl
POP
POP
HL
BC
EAFA
11
EE2F
LD
DE f PLIST
EAFD
AF
XOR
A ;FLAG
EAFE
08
EX
AF.AF , ; A f =0
EAFF
EB00
79
B7
LD
OR
A,C
A
EB01
28
IF
JR
Z f FINIS
EB03
FE
06
CP
6
EB05
20
02
JR
NZ f OPBN6
EB07
0D
DEC
C ; C=5
EB08
08
•
EX
AF.AF* ;A,<>0
EB09
46
0PEN6 :
LD
B f (HL)
EB0A
23
INC
HL
EB0B
1A
0PEN7 :
LD
A f (DE)
EB0C
13
INC
DE
EB0D
B7
OR
A ;SEPARATOR
EB0E
CA
EE26
JP
Z,ERR
EB11
B8
CP
B
EB12
20
F7
•MATCH
JR
NZ f OPEN7
EB14
D9
EXX
EB15
12
LD
(DE),A
EB16
D9
EXX
EB17
1A
OPEN75 :
LD
A,(DE)
EB18
13
INC
DE
BB19
B7
OR
JR
A
EB1A
20
FB
NZ.OPEN75
EB1C
D9
0PEN8 :
EXX
EB1D
13
INC
DE
EB1E
D9
EXX
EB1F
0D
DEC
C
EB20
20
E7
•
JR
NZ f OPEN6
EB22
08
FINIS :
EX
AF t AF»
EB23
B7
OR
A
EB24
28
10
JR
Z f SETZ
EB26
7E
LD
A f (HL) ;ENDCODE
EB27
FE
40
CP
40H
EB29
DA
EE26
JP
C f ERR
EB2C
FE
80
CP
80H
EB2E
D2
EE26
JP
NC f ERR
EB31
E6
IF
AND
1FH
EB33
D9
EXX
EB34
12
LD
(DE) f A ;STORE
EB35
D9
•
EXX
EB36
F3
SETZ :
DI
;SBT ZCTC.ZSIO
EB37
CD
EB6A
CALL
INITBF
EB3A
01
1FA9
LD
LD
BC f ZCTC^l ; CH0
EB3D
3E
47
A f 010001 11B ;MODE
EB3F
ED
79
OUT
(C) f A
EB4 1
3A
EE2E
LD
A f (CTR)
EB44
ED
79
•
OUT
(C) f A ;T CONSTANT
EB46
21
EE4C
t
LD
HL,SIOSA
EB49
01
1F99
LD
BC , ZSIO+l ;CH A
EB4C
3E
0F
LD
A f 15
EB4E
CD
EB63
•
CALL
SETSIO
EB51
21
EE5B
>
LD
HL.SIOSB
EB54
01
1F9B
LD
BC,ZSIO+3 ;CH B
EB57
3E
05
LD
A f 5
EB59
CD
EB63
CALL
SETSIO
EB5C
3E
FF
LD
A f 0FFH
EB5E
32
EE60
LD
(OPENF) f A
EB61
FB
El
EB62
C9
•
RET
EB63
04
SETSIO :
INC
B
EB64
ED
A3
OUT I
EB66
3D
DEC
A
EB67
20
FA
JR
NZ,SETSIO
EB69
C9
RET
第 7 章通 信 AJ7
Pit
INITBF :
XOR
32
EE6A
LD
21
EE6B
LD
22
EE66
LD
22
EE68
•
LD
32
EE62
t
LD
32
EE63
LD
32
EE64
LD
32
EE65
LD
C9
•
RET
AF
CLOSE :
XOR
32
EE60
•
LD
3A
FE
EE4B
4F
t
LD
CP
C0
RET
3A
FE
EE4A
20
LD
CP
C8
RET
CD
EDCD
CALL
C9
•
RET
3A
77
EE6A
LOC :
LD
LD
23
INC
36
00
LD
C9
•
RET
;BREAK
B.A.F
3A
BE6A
QEOF :
LD
B7
OR
C8
RET
3A
FE
EE4A
20
LD
CP
C8
RET
E5
PUSH
2A
EH68
LD
46
LD
El
POP
B8
28
02
CP
JR
AF
XOR
C9
RET
F6
FF
QEOF1 :
OR
C9
•
RET
CD
EBA0
EOF :
CAL し
11
28
0000
01
LD
JR
IB
DEC
73
EOF1:
LD
23
INC
72
LD
C9
•
RET
F3
INTRSR :
DI
F5
PUSH
C5
PUSH
D5
PUSH
B5
•
PUSH
01
1F99
t
•
LD
3E
01
INTR1 :
LD
ED
79
OUT
ED
78
•
IN
0B
•
DEC
ED
78
IN
2A
EE66
LD
77
LD
23
INC
E5
PUSH
01
B7
EEEB
LD
OR
ED
El
42
SBC
POP
20
03
JR
A
(QLEN) f A
HL f Q0
(HEAD) 9 HL
(TAIL) f HL
(LASTX),A
(XFLAG) f A
(TKIN) f A
(RKIN) t A ;RESET MODE
A
(OPENF),A
A, (IOC)
• 0 ,
NZ
A,(ECODE)
20H
Z
PPUTC ;TX ECODE
A f (QLEN)
(HL) f A
HL
(HL) f 0 ;RET SIZE
A f (QLEN)
A
Z ; EMPTY
A 9 (ECODE)
20H
2 ;NO ECODE
HL
HL,(TAIL)
B t (HL) ;NOZOKU
HL
B
Z f QEOFl
A ;SET Z
0FFH ;SET NZ
QEOF
DE f 0
Z.EOF1
DB
(HL) f E
HL
(HL) t D
;INT ROUTINE
AF
BC
DE
HL
BC,ZSIO+l
(C),A ; RR1
A, (C)
BC
A f (C)
HL t (HEAD)
(HL) f A
HL
HL
BC , Q1
A
HL f BC
HL
NZ f INTR2
EBB9
EBBC
KBBF
EBC1
EBC2
EBC3
EBC4
EBC5
EBC6
BBC7
EBC8
EBC9
EBCA
EBCB
EBCE
EBD0
EBD2
EBD4
EBD5
EBD7
EBDA
EBDB
EBDC
EBDD
EBE0
EBE1
EBE3
EBE4
EB6A
EB6B
EB6B
EB71
EB74
EB77
EB7A
EB7D
EB80
EB83
EB84
EB85
EB88
EB8B
EB8D
EB8E
EB91
EB93
EB94
EB97
EB98
EB9B
EB9C
EB9D
EB9F
03458 ABCF 0124568
AAAAAAAAABBBBBBB
CQ BBCO CQ CQ B B CP B CPBCO CQ BB
EEEEEEEEEEEEEEEE
138 試験に出る XI
EBE6
21
EE6B
LD
HL 9 Q0
EBE9
22
EE66
INTR2 :
LD
(HEAD),HL
EBEC
21
EE6A
LD
HL 9 QLEN
EBEF
34
•
INC
(HL)
EBF0
FE
13
t
CP
XOFF
EBF2
20
05
JR
NZ,INTR3
EBF4
32
EE62
し D
(LASTX) f A
EBF7
18
08
JR
INTR4
EBF9
FE
11
INTR3 :
CP
XON
EBFB
20
04
JR
NZ f INTR4
EBFD
AF
XOR
A
EBFE
32
EE62
LD
LD
(LASTX) f A
EC01
3A
EE6A
INTR4 :
A f (QLEN)
EC04
3C
INC
A
EC05
FE
40
CP
QMAX
EC07
D4
ECU
•
CALL
NC,SWAIT
EC0A
El
9
POP
HL
EC0B
D1
POP
DE
EC0C
Cl
POP
BC
EC0D
FI
POP
AF
EC0E
FB
El
EC0F
ED
4D
•
RETI
EC11
01
1F99
SWAIT :
LD
BC.ZSIO+l
EC14
3A
EE45
LD
A f (PARAM40)
EC17
FE
4R
CP
f N f
EC 19
C8
RET
Z ;NO
f R #
EC1A
FE
52
CP
EC1C
28
11
JR
Z f SWAITl
EC1E
FE
58
CP
f X f
EC20
C0
RET
NZ
EC21
3A
EE63
LD
OR
A f (XFLAG)
EC24
B7
A
EC25
C0
RET
NZ
EC26
3E
13
LD
LD
A t XOFF ;X
EC28
32
EE63
(XFLAG),A
EC2B
CD
ED77
CALL
PPUTC0
EC2E
C9
RET
EC2F
01
1F99
SWAIT1 :
LD
BC,ZSIO+l
EC32
3E
05
LD
A i 5
EC34
ED
79
OUT
(C) t A
EC36
3A
EE54
LD
A,(WR541)
EC39
E6
FD
AND
1111 1101B
EC3B
ED
79
OUT
(C) ,A
EC3D
C9
•
RET
EC3E
3A
EE45
SOK :
LD
CP
A f (PARAM^O)
EC4 1
FE
4E
f N f
EC4 3
C8
RET
Z
QUE
GET XOFF
GET XON
SEND WAIT
EC44
EC46
EC48
EC4A
EC4B
EC4E
EC4F
EC50
EC51
EC54
EC56
EC59
EC5A
EC5D
EC5F
EC61
EC64
EC66
EC68
FE 52
2812
FE 58
C0
3A EE63
B7
C8
AF
32 EE63
3E 11
CD ED77
C9
011F99
3E 05
ED 79
3A EE54
F6 02
ED 79
C9
SOK1 :
CP
JR
CP
RET
LD
OR
RET
XOR
LD
LD
CALL
RET
LD
LD
OUT
LD
OR
OUT
RET
;RES RTS
f R f
Z•SOK1
f X f
NZ
A f (XFLAG)
A
Z
A
(XFLAG) f A
A f XON
PPUTC0
BC,ZSIO+l
A.5
(C) f A
A,(WR5+1>
00000010 B
(C) ,A
: SET RTS
EC69
EC6C
EC6D
EC70
EC72
EC7 4
EC77
EC79
CD ECA4
47
3A EE46
FE 53
20 24
3A EE61
FE 7F
20 ID
XGETC
CALL
LD
LD
CP
JR
LD
CP
JR
PGETC : GET CHAR
B f A ;SAVE
A f (PARAM+l>
, S ,
NZ t XGETC4
A f (MASK)
111111 IB
NZ f XGETC 4
第 7 章通 倍 A39
CD
0330
PGETC : CALL
QBREAK
CA
EE2A
JP
Z,BREAK ; BREAK?
3A
EE6A
LD
A t (QLEN)
B7
OR
A
28
F4
JR
•
Z,PGETC
F3
' DI
3A
EE6A
LD
A,(QLEN)
; RE-GET
5F
LD
Et A
;SAVE
QLEN
2A
EE68
LD
HL,(TAIL)
3A
EE61
LD
A f (MASK)
A6
AND
(HL)
57
LD
D t A ;GET DATA
23
INC
HL
E5
PUSH
HL
01
B7
EEEB
LD
OR
BC,Q1
A
ED
42
SBC
HL f BC
El
POP
HL
20
03
JR
NZ f GETCl
21
EE6B
LD
HL t Q0
;QUE
•
•
22
EB68
GETC1 : LD
(TAIL) t HL
7B
3D
LD
DEC
A f E
A
• GET
QLEN
32
EE6A
LD
CP
(QLEN) t A
FE
30
QMAX-16
D5
PUSH
DE
DC
EC3E
CALL
C.SOK
;SEND
OK
FB
El
D1
7A
POP
LD
DE
A,D
C9
RET
0A0H-080H
C f XGETC4
7 f B ; T0 KANA
A f B
E5
C5
LIP1 :
PUSH
PUSH
HL
BC
••SAVE COUNTER
CD
0330
LIP1L :
CALL
QBREAK
; BREAK?
CA
EE2A
JP
Z,BREAK
3A
EE6A
LD
A f (QLEN)
B7
OR
A
28
F4
JR
Z f LIP1L
CD
EBA0
CALL
QEOF
28
0A
JR
Z.LIP1L1
;S AND 7 BITS
3A
EE65
LD
A f (RKIN)
B7
OR
A
78
LD
A f B
20
06
JR
NZ,XGETCl
FE
0E
CP
SO ; TO
KANA MODE
28
07
JR
Z f XGETC2
18
10
•
JR
XGETC4
FE
0F
XGETCl :
CP
SI
20
06
JR
NZ f XGETC3
AF
XOR
A
32
EE65
XGETC2 :
LD
(RKIN) f A
;CLEAR
18
D7
JR
XGETC
••AGAIN
LINPUT : EX DE,HL
PUSH HL
INC HL
LD A f B
CP 2
JP C f ERR ; N0 SPACE
DEC B ;DEC COUNTER
LD C f 0
EC7B
EC7E
EC7F
EC80
EC82
EC84
EC86
EC88
EC8A
EC8C
EC8D
EC90
EC92
EC94
EC96
EC98
EC99
EC9A
EC9B
BC9E
BC9F
BCA0
ECA1
ECA3
ECA4
ECA7
ECAA
ECAD
ECAE
ECB0
ECB1
ECB4
ECB5
ECB8
ECBB
ECBC
ECBD
ECBE
ECBF
ECC2
ECC3
ECC5
ECC6
ECC8
ECCB
ECCE
ECCF
BCD0
ECD3
ECD5
ECD6
KCD9
ECDA
ECDB
ECDC
ECDD
ECDE
ECDF
ECE0
ECK1
ECE3
ECB6
ECE7
ECE9
ECEA
ECEB
ECEE
ECF1
ECF4
ECF5
ECF7
ECFA
5 D 1 7 3 6 9
E c E 7 2 3 c
p R E D E
c J s L R
2 E 0
0 E 0
B538EA5E
HE27FD00
140 拭験に出る XI
;GET EOF
;REQUEST 0 CHAR
;COUNTER
;LEN
DE ;SAVE ADDR
DE 9 HL
A f (HL)
HL
B
NC f ERR : TOO SHORT
•INPUT n CHAR
ED35
D5
INPUTN :
PUSH
ED36
BD37
EB
7E
23
EX
LD
ED38
INC
ED39
B8
CP
JP
ED3A
D2 EE26
; A<B
ED3D
05
DEC
ED3E
B7
OR
ED3F
2812
JR
ED41
47
LD
ED42
0E 00
LD
ED44
ED45
ED46
ED49
ED4A
ED4B
ED4C
ED4D
ED4E
ED50
ED51
ED52
C5
E5
CD EC69
El
Cl
77
23
0C
10 F4
El
71
C9
IPN1 :
PUSH
PUSH
CALL
POP
POP
LD
INC
INC
DJNZ
POP
LD
RET
BC
HL
XGETC
HL
BC
(HL) f A
HL
C
IPN1
HL
(HL) f C
STORE CODE
TOP ADDR.
STORE LEN
ED53
ED54
ED55
D1
12
C9
IPN2 :
POP
LD
RET
DE
(DE) f
;STORE 0
ED56
ED59
ED5B
BD5E
ED61
ED63
ED64
ED66
CD ED68
3E 0D
CD EDCD
3A EE47
FE 4C
C0
3E 0A
18 65
PRINT
CALL
LD
CALL
LD
CP
RET
LD
JR
PRINTS
A f CR
PPUTC
A,(PARAM42)
NZ
A f LF
PPUTC
;,C
POP
BC
POP
HL
LD
A,C
CP
CR
JR
NZ f LIPL2
DEC
HL
•
JR
LIPL2
;SUTE CR
LIP1L1 :
CALL
XGETC
POP
POP
BC
HL
;1 LINE?
PUSH
AF
LD
A f (PARAM+3>
CP
f L f
JR
Z,LIPLl
POP
AF
CP
CR
JR
Z.LIPL2
JR
LIP2
LIPLl :
LD
A f C
CP
CR
JR
NZ f LIPL 3
POP
AF
CP
JR
LF
NZ f LIP2
DEC
HL
•
JR
LIPL2
LIPL3 :
POP
AF
LIP2:
LD
LD
(HL) f A
LIP3 :
C f (HL)
;LAST CHAR
INC
HL
DJNZ
LIP1
; FULL?
LIPL2 :
POP
DE
OR
A
SBC
HL t DE
EX
DE f HL
DEC
E
LD
(HL) ,E
;STORE LEN
RET
ECFC
Cl
ECFD
El
ECFE
79
ECFF
FE
OD
ED01
20
2A
ED03
2B
ED04
18
27
ED06
CD
EC69
ED09
ED0A
Cl
El
BD0B
F5
BD0C
3A
EE48
ED0F
FE
4C
ED11
28
07
ED13
FI
BD14
FE
0D
BD16
28
15
ED18
18
0E
ED1A
79
ED1B
FE
0D
ED1D
20
08
ED1F
FI
ED20
FE
0A
ED22
20
04
ED24
2B
ED25
18
06
2
N
p
I A 0
t 9 I
B A z B c
c 2
B 5
17E3017DBD39
F 7421 DBEE17C
789A BDEF1234
2 2 2 2 22223333
D D D D
E E E E
EDEDBDBDEDEDBDBD
第 7 章通 信
DE
BC
DE
PUTC
PUTSL
PRINTS : LD
OR
RET
PUTSL : LD
INC
PUSH
PUSH
CALL
POP
POP
DJNZ
RET
0E
EDCD
EE64
PPUTC0 :
PUSH
AF
LD
BC,ZSIO+l
PUTCL0 :
LD
A f 10H ;RESET STAT
OUT
(C) tA
IN
A f (C) ;GET RR0
BIT
2 f A ;TX BUFF
•
JR
Z f PUTCL0
1
CALL
JR
LD
CHTXOK ;TX OK?
Z f PUTOK
A f 10H ;STAT RESET
OUT
(C) f A
#
JR
PUTCL0 ;LOOP
PPUTC1 :
LD
A, (HU
•
JR
PPUTC
PUTC :
LD
B f A
LD
A, 《 PARAM+l>
CP
1 S 1
JR
NZ f PUTC0
t
LD
A,(MASK)
CP
111111 IB
m
JR
NZ f PUTC0
; # S f AND 7 BITS
BIT
7,B
JR
Z,NKANA ;NOT KANA
LD
A f (TKIN)
OR
A
JR
NZ,IKANA
PUSH
BC ;SAVE IT
LD
A f SI ;SHIFT IN
CALL
PPUTC
LD
(TKIN) f A
•
POP
BC
IKANA :
LD
A f B
7FH ;SEND 7 BITS
AND
•
JR
PPUTC
NKANA :
LD
A,(TKIN)
OR
A
•
JR
Z f PUTC0 ;NO KANA MODE
t
PUSH
BC ;SAVE IT
LD
A, SO ;SHIFT OUT
CALL
PPUTC ;PUT ANY HOW
XOR
A
LD
(TKIN) f A
•
POP
BC ; B=IT
PUTC0 :
LD
A,B ;DATA TO TX
PPUTC:
PUSH
AF
LD
BC,ZSIO+l
PUTCL :
CALL
JP
LD
QBREAK ; BREAK?
Z, BREAK
A f 10H ;RESET STAT
OUT
(C) f A
IN
A f (C) : GET RR0
BIT
2,A ;TX BUFF
•
JR
Z, PUTCL
t
CALL
JR
LD
CHTXOK ;TX OK?
Z f PUTOK
A.10H : STAT RESET
EDC1
EDC2
EDC4
EDC7
EDC8
EDCB
EDCC 78
EDCD F5
EDCE 011F99
EDD1 CD 0330
EDD4 CA EE2A
EDD7 3E 10
EDD9 ED 79
BDDB ED 78
EDDD CB 57
EDDF 28 F0
EDEl CD EE09
EDE4 28 06
EDE6 3E 10
ED77
ED78
ED7B
BD7D
ED7F
ED81
ED83
F5
011F99
3E 10
ED 79
ED 78
CB 57
28 F6
ED85
ED88
ED8A
ED8C
ED8E
CD EE09
28 62
3E 10
ED 79
18 EB
ED90
ED91
7E
18 3A
ED93
ED94
ED97
EI)99
47
3A EE46
FE 53
20 31
ED9B
ED9E
EDA0
3A EE61
FE 7F
20 2A
EDA2
EDA4
EDA6
EDA9
EDAA
EDAC
EDAD
EDAF
EDB2
EDB5
CB 78
2815
3A EE64
B7
20 0A
C5
3E 0F
CD EDCD
32 EE64
Cl
EDB6
EDB7
EDB9
78
E6 7F
1812
EDBB
EDBE
EDBF
3A EE64
B7
28 0B
5 E D F 21
c 3 c A 3 c
3
9
D 5
E F
878A355D1109
7BC11CDCDC1C
89ABCDE F2346
666666667777
DDDDDDDDDDDD
EEEEEEEEEEEE
試験に出る XI
;P AREA
;5+l=6
EE45
EE4A
PARAM : DS
ECODE: DS
PUTOK :
OUT
(C) f A
JR
PUTCL
;LOOP
DEC
BC
;DATA PORT
POP
DE
; D=CHAR
LD
A f (MASK)
AND
D
OUT
(C) ,A
;TX DATA
LD
OR
A t (QLEN)
A
; EMPTY?
RET
Z
: DROP XON f XOFF
PEND0 :
LD
HL f (TAIL)
LD
A f (HL) ;NOZOKU
CP
XON
JR
Z,PENDl
CP
XOFF
RET
NZ
PENDl :
CALL
PGETC1 ;DROP
•
JR
PENDO
CHTXOK :
LD
D,A ;SAVE RR0
LD
A t (PARAM4^0)
CP
f N f ;NO CON
RET
Z
CP
f R f ;RTS
JR
NZ,CHX
LD
A f D
CPL
;REVERSE
BIT
5 f A ;RTS
•
RET
CHX :
CP
JR
T
Z f CHXl
CHX1 :
XOR
RET
DI
LD
OR
El
RET
A
;ENGIMON
A f (LASTX)
ERR :
•
BREAK :
LD
JP
DI
JP
A f 5
(IX)
••ILL
•
BBREAK
CTR :
•
DS
i
;CTC
PLIST :
DB
*XRN
,0
DB
f SN f
0
DB
•CL ,
0
DB
f CL f
❶
DB
1 JN 1
0
PDFLT
DB
NNLLN 1 t 20H
2A EE68
7E
FE 11
28 03
FE 13
C0
CD EC9A
18 F0
IOC :
•
DS
1 ;
SIOSA :
DB
00011000 B
WR1 :
DB
l f 10H
WR2 :
DB
2 t 00H
WR4 :
DB
4 f 00H
WR5 :
DB
5 f 00H
WR6 :
DB
6 , 00 H
WR7 :
DB
7 f 00H
WR3 :
•
DB
3 f 00H
SIOSB :
DB
18H
DB
1.00H
•
DB
2,INTRSV
•
OPBNF :
DB
0 ;(
;OPEN MODE FLAG
; WR0
;OPEB FLAG
EE5B 18
EB5C 01 00
EE5E 02 5C
EE60 00
EE09
57
EE0A
3A
EE45
EE0D
FE
4E
EE0F
C8
EE10
FE
52
EE12
20
05
EE14
7A
EE15
2F
EE16
CB
6F
EE 18
C9
EE19
FE
58
EE1B
28
02
EE1D
AF
EE1E
C9
EE IF
F3
EE20
3A
EE62
EE23
B7
EE24
BE25
FB
C9
EE26
3E
05
EE28
DD
E9
EE2A
F3
EE2B
C3
1FCA
EE2E
EE2F
58
52 4E
00
EE33
53
4E 00
EE36
43
4C 00
EE39
43
4C 00
EE3C
4A
4E 00
EE3F
4E
4E 4C
4C
EE43
4E
20
EDE8 ED 79
EDEA 18 E5
EDEC 0B
EDED Dl
EDEE 3A EE61
EDF1 A2
EDF2 ED 79
EDF4 3A EE6A
EDF7 B7
KDF8 C8
51
9CDF1347
FFFF0000
DDDDEEEE
EEEEEEEE
0 0 0 0 0 0 0
10 0 0 0 0 0
81245673
10000000
B CDF13579
4 44455555
E EEEEEEEE
E EEEEEEEE
第 7 章
EE61
MASK :
DS
1
;DATA MASK
EE62
LASTX :
DS
1
;R FLAG
EE63
XFLAG :
•
DS
i
;T FLAG
EE64
TKIN :
DS
DS
i
;R KANA FLAG
EE65
RKIN :
•
1
;T KANA FLAG
EE66
t
HEAD :
DS
2
;QUE HEAD
EE68
TAIL :
DS
2
;QUE TAIL
EE6A
QLEN :
DS
1
;Q LENGTH
EE6B
Q0 :
DS
QMAXX
EEEB
Ql :
•
END
リスト 7-2 通信プログラムのダンプリスト
EC80
EC88
EC90
EC98
ECA0
ECA8
ECB0
ECB8
ECC0
EC00
EC08
EC10
EC18
EC20
EC28
EC30
EC38
BC40
EC48
EC50
EC58
EC60
EC68
EC70
EC78
EB00
EB08
EB10
EB18
EB20
EB28
EB30
EB38
EB40
EB48
EB50
EB58
EB60
EB68
EA80
EA88
EA90
EA98
EAA0
EAA8
EAB0
EAB8
EAC0
EAC8
EAD0
EAD8
EAE0
EAE8
EAF0
EAF8
SUM : 5A 5C 15 9E 8D 4E 2B DF
SUM : 3A 9E FD 4212 B4 78 4C
EB80
EB88
EB90
EB98
EBA0
BBA8
EBB0
EBB8
EBC0
EBC8
EBD0
EBD8
EBE0
EBE8
EBF0
EBF8
SUM : 3D D9 4D E8 87 EB D2 A8
SUM : 1A E2 8C E2 74 31 D8 D6
EA00 C3
EA08 EC
EA10 56
EA18 C3
EA20 EE
EA28 EB
EA30 3D
EA38 5C
EA40 EE
EA48 FE
EA50 C3
EA58 04
EA60 EE
EA68 D2
EA70 30
EA78 3D
)564
89
67
0A
DB
EC
7D
64
8F
C3
)9CD
CE
49
71
F5
13
7E
EF
7F
8C
20
C5
9F
53
DB
1C
78
EB70 EE 22 66 EE 22 68 EE 32 : 0E
EB78 62 EE 32 63 EE 32 64 EE : 57
SUM : 07 6C 65 9E F3 F0 F7 30 1771
0E87A4E13
1EF7CFE00
85B1 38850
16CE026E2
722 C07A31
030E3B22E
8F84DEF72
2A3ACE554
E60D9AE6D
002CC6EAE
E0E50AAE7
F2FE036EB
6F796EA1E
00DC3E36E
0E883A3AB
2F1722F3E
4DE 83145287 D9EE8
DEF 51054 1C7E7EF7
0BEEE9AA87D5D6E7
4FEF3C332BC0E4EB
E1510D992E1E2A1E
FF41CE7C5E13036E
C1A877D9E3EF67A5
3C32B7B7F631F436
E1F2ED5D8AE9EC4A
ED15EC0EC3E9EE23
A19E3EEDE 031440 D
6E9F6E3F4C605A21
AC18A3F6E829AD30
3E0C361EF53C3C52
E1DE029EEEFD99EF
E144C39EEFAE7CF7
D6ADE6DDC3E00B
0210F2CE 463626
2A99E2371DF2D1
0CDD7DF42C1332
0723009 E9FBF3E
2B111 803709 FAE
63998 E2FDE1EDA
01 DD2F11E303E6
EA7B7E99EFEB42
F1FFBEDAE1EE03
F 30086 F1E9B39F
122202102956 CA
86877 A6BA11DB9
24BBEDEE 302 CFC
78E300EA9EB5EA
B0E124E67EE0EF
808B 660766322599
2027212 BFF2D54D7
C6FEA5D1F0E321B8
314EDF3F 08703 1E0
03E65E2EF6EE3E0F
82F23E2E0FEFBEBA
6E4266B13F4E7FDE
171CD2C6005E83EE
7AB 53252 EE 26710 F
05042 D03EE 328202
008EE48FAA8AC561
3C2F7022E50D3E01
06E4FE7A5261E 511
41415 FB7C3F3BC0C
62E62E0BA1266EE1
10F0BREFE00D2EEE
D44B310A575D610E
70228935 D76A71D7
EA99E6F851AEB 482
E4CCE4F2F02E 6316
0AD0AE603E8B1EE2
63E04EF0F37E2EE3
20D6A8909FD13A2F
3CC336C0C1E0066A
FFD38AF129B 50124
A4C2C2A1790E2230
9E 87752 B 3183 1E50
CFC7BE0E2072EE02
EE0EE 88035 D 72601
EE2EEC2A7EE 74621
5BEAA08DB59ED23E
64F662BC1D7EE21F
2AEAAE1915D67EE8
33E33FEC0CE6BEF0
DC03FA11E80F9996
9AF2B3460E9EE9C0
D3B04E26B 36675 A1
DCE68E2200D20F3F
3D9AD0BA8882E2BE
CEB3C6EC227DF0CE
B83D 526793 E7065E
E6CEC3CB44E03D02
43B05F18EEBE 6082
8CE9DF27FF4FDD23
3D837E3B372E367 A
CE9C03FE203E21B7
A53C81DBE8E6EEF8
E3CE2DFF72E27EAF
E3DA 71005 F6AF618
1CE9BC 20042 D4201
A 798ED1EDE6585C60
5 8E0ABE0C9F1C9350
c
B 15B7A 47024 EF38
3 349B7A79
A 2 4 E A 8
c
144 試験に出る XI
EE00
EE08
EE10
EE18
EE20
EE28
EE30
EE38
EE40
EE48
EE50
EE58
EE60
ED0O
ED08
ED10
ED18
ED20
ED28
ED30
ED38
ED40
ED48
ED50
ED58
ED60
ED68
ED70
ED78
SUM : CA 40 7A D2 2F 72 2F 93
SUM : 58 3A 50 EE 95 E4 39 BE
ECC8 21
ECD0 32
ECD8 EC
ECE0 78
ECE8 00
ECF0 EE
ECF8 A0
5DF0
3F
C8
58
B4
48
D2
D0
75
C5
08
16
7A
00
CDF1
F7
FI
B4
C3
66
29
D4
A5
47
38
FC
40
BD
8B
D5
5A
SUM : B8 97 FI8A CD 80 F9 BF E0FD
ED98 53 20 313A
EDA0 20 2A CB 78
EDA8 EE B7 20 0A
EDB0 CD ED 32 64
EDB8 7F 1812 3A
EDC0 0B C5 3E 0E
EDC8 32 64 EE Cl
EDD0 IF CD 30 03
EDD810 ED 79 ED
EDE0 F0 CD 09 EE
EDE8 ED 7918 E5
EDF0 EE A2 ED 79
EDF8 C8 2A 68 EE
61
EE
FE
7F
AA
28
15
3A
64
68
C5
3E
0F
CD
AE
EE
Cl
78
E6
5D
64
EE
B7
28
14
CD
CD
ED
AF
52
78
F5
01
99
4C
CA
2A
EE
3E
3F
78
CB
57
28
25
28
06
3E
10
30
0B
D1
3A
61
DA
3A
6A
EE
B7
3F
7E
FE
11
28
FD
SUM : 0D 24 66 AA 33 B7 5D 118D3D
ED80 78 CB 57 28 F6 CD 09 EE : 7C
ED88 28 62 3E 10 ED 7918 EB : 41
ED90 7E 18 3A 47 3A 46 EE FE : 83
リスト 7-3 サンプルプログラム
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
CLEAR &HEA00
IF MEM$(&HEA00 f 3)<>HEXCHR$( M C3 IB EA M )
DEFUSR0=&HEA00
DEFUSRl=&HEA00+3
DEFUSR2=&HEA00+6
DEFUSR3=&HEA00+9
DEFUSR4 = &HEA00*f 12
DEFUSR5 = &HEA00*f 15
DEFUSR6=&HEA00+18
DEFUSR7 = &HEA00-f21
DEFUSR8=&HEA00+24
DEFUSR9 = &HEA00-f27
LOADM "RS.OBJ
OPEN
f CLOSE
'LINPUT
1 INPUTN
'PRINTS
, PRINT
,LOC
,EOF
, PGETC1
'PPUTCl
: STR
: *
: STR
: STR
: STR
: STR
: I NT
: INT
: INT
: INT
A$ = USR0( M 06N83XNCCNZ M ) : 9 OPEN
A$=USR1 (•*••) ノ CLOSE
C=10 : A$=USR2(STRING$(C f M . M ) ) : ,LINPUT
C=10 : A$=USR3(CHR$(C)+STRING$(C f M . M )) :, INPUTN
A$=USR4("STRINGS") : , SEND STRING
A$=USR5( M ONE LINE") : , SEND 1 LINE
A=USR6(0) : , GET BUF SIZE
A=USR7(0) : 9 EOF ?
A=USR8(0) : , GET 1 BYTE
A = USR9(0) : 1 PUT 1 BYTE
リスト 7-4 ffi 単なターミナルプログラム(100〜210行はリスト 7_ 3 と同じ)
100 CLEAR &HEA00
110 IF MEM$(&HEA 00,3
120 DEFUSR0=&HEA00
130 DEFUSRl=&HEA00+3
140 DEFUSR2=&HEA00+6
: f OPEN
: STR
: 1 CLOSE
: 拿
: f LINPUT
: STR
THEN LOADM M RS.OBJ
88F358CE127C
1C6F 05442005
CEB9E 5303002
E4CC 31408100
AEFF9F0ED160
9F2AC104C000
DEA2BAEA0801
CE70FC 442100
05587330 E058
C402BC 504201
3A08E30CC300
1325EF044B00
E72E29E3C343
F55F6E444C00
30E9AD20E7000
0FFC3D 5044000
9E511DE 894875 D5D
6F1FFE726F646CFE
DE8867B7D0DA 8599
CE200BEBC1C31DC7
78D 081555 C9DA55D
24021 DD0E0CE0CFE
8AEDBC9E532DE300
13F02BCEC21C 3111
B51E 403607 1D0A1E
2FFF 017207 DCC1C3
A17903D2E19DC81F
2E 0722 1D0CC04CD1
018 EAEB 8711 EE7D9
2C2004EB4E73FBE9
DCC8E 7232 cl D.E 8 31
0E41F 7521 EEEE790
A 7 E 9 E 0 6
A A E 7 9 2 D
D E 3 E A D E
3 3 2 0 2 c F
B c 5 5 A 4 9
7DE0CF7
E 5 B E 3 81
E D E E 0 2 E
8 0 9 6 0 7 1
6 3 c 2 3 B c
2 E A A D E A
2 F 7 D c E 0
E 12 5 A 8
E D 0 c 6 2
E
E
B A B E 5 A B
6 6 F F E 3 E
第 7 章通 信 M
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
DEFUSR3=&HEA00+9
DEFUSR4=&HEA00+12
DEFUSR5 = &HEA00-f 15
DEFUSR6 = &HEA 004.18
DEFUSR7 二 &HEA00+21
DEFUSR8=&HEA00+24
DEFUSR9=&HEA00+27
• 100 一 210 キ • b 勹 ハ リスト3
A$=USR0("C6N83XNCCNZ"}
L$ = M H
: f INPUTN
STR
: 1 PRINTS
STR
: •PRINT
: *L0C
STR
I NT
: f E0F
I NT
: »PGETC1
I NT
: , PPUTC1
I NT
モノヲツカウノ f アル
: 'OPEN
IF USR7(0) THEN PRINT "GET END":END 1 EOF
A=USR6(0) : IF A=0 THEN 300 1 LOC > 0?
A$=USR3(CHR$(1 f 0))
A$=RIGHT$(A$ f 1) : A=ASC(A$) ,GET AND DISPLAY
IF (A>=&H20) OR (A=13) THEN PRINT A$; : GOTO 260
C$=INKEY$(0) ,READ KEY
IF (C$=CHR$(0)) OR (L$=C$) THEN 340 * YUUKOU ?
IF C$=CHR$(13) THEN A$=USR5 (••••>: GOTO 340
A$=USR4(C$) ,TX IT
L$=C$:GOTO 250
ここでこの章のプログラムの 手抜きなどに ついて 書いて おくことにする。
まずは XON , XOFF 制御についてである。やっててだんだん面倒になってきたので,「送
られてきた XON / XOFF はバッファにたまる」ようになっている0ただしバッファのトッ
プが XON もしくは XOFF であったならば,「こちらからデータを送るときにチェックし
て捨てる」ようにしている。もしも向こうから 「 XON / XOFF と他のコードも混ぜて送っ
てきたら」受信に混ざりこむことになる0必要ならば表示ルーチンなどで取り除いていた
だきたい。これは,バイナリデータとして,たまたま XON / XOFF ( ll H /13 H ) が送られて
くる場合もあるのでこうしたのだが,本当はどうすべきだったのであろうか。また CLOSE
時の動作もよく分かんないのである 。 turbo BASIC では「0」でオーブンしたときだけエ
ンドコードを送るようになっているようであるが, 「 C 」 では送らないようである。またそ
の逆のエンドコードを受け取ったときの動作も不明瞭である 。 turbo BASIC では,
LINPUT がエンドコードを受け取ったときは1行が終了したとみなしてリターン,
INPUTS で入力文字数を指定した場合はエンドコードが来たとしても,指定文字数まで
リターンしない,などとなっている0ここらへんの細かな動作は, BASIC のマニュアルに
きっちり書いてあるわけではないので, なんだかよくわかんな いのである。
おっとここで思い出した。この章のブログラムでは, 「 EOF はこれから読み出そうとして
いるデータがエンドコードだったら 一 1を返す」ようになっている。よって不幸にして
INPUT $ などでその「エンドコードを読み出してしまったりすると」 EOF でなくなって
しまうのである。注意していただきたい。しかし LINPUT でエンドコードは読み出さない
ようになっているから,エンドコードが一度来たら,それ以降はずっと EOF である。
なんだかんだ書いたが,はっきり言って結局は USR 8, USR 9 の「生データ読み出し,書
き込み」が最終兵器となるような気がする。つらつら考えるに, この二つの 機能 + L 0 C 関
数 +0 PEN コマンド +あぶったイカさえあれば,ほかには何もいらないよ一な気がしてし
まうのである。というわけで,本当にやるのならば大いに改造していただきたいと思うし
だいである。
U6 試験に出る XI
□ MA はへビー級である
■第日章
1 DMA はへ匕一級 I あ3
この章では, Z 80 ファミリーの中でも特に 「荒技使い」 との呼び声が高い Z 80 DMA に
ついてやるのである。残念ながらこの石は turbo にしか付いていないが,それはそれで仕
方がないのである。ちなみにこの石をノン turbo の XI に付けようとする場合は, 本体基板
に対する改造が必要となる。 CTC や SIO のようにボードに 載せ て I / O スロ.ットにさすと
いうことはできないのである。
DMA というのは l^irect Memory △ ccess 」 の頭文字を取って作られた言葉である。そ
の点からすれば, DMA 動作をする LSI は DMAC (DMA Controller ) と呼ばれるべきな
のだが, Zilog 社はアルファベット3文字にしたかったようである。それはさておき,この
石はデータ転送を主要な業務とする LSI である。 M は Memory の M であるが,これは別
にメインメモリとは限らず, I / O でもよいのである0この点,誤解のないよ一に0
さて, Z 80 ファミ リーには PIO , CTC , SIO などがあるが, DMA はこの中でも CPU と
互角の地位にあり,他の周辺 LSI とは一線を画しているのである。もしも DMA に聞いて
みたならば,「わしゃ 一, 偉 いんでい! J と答えるはずである。それはなぜかというと , DMA
は「データ転送に関しては CPU と同等の立場に立っている」からなのである。う〜ん,こ
れは非常に曖昧な表現である。 曖昧ついでに 書いてしまうが, DMA がどれだけ CPU と
同等かというと, 「 DMA が動いている間は, CPU が止まらざるを得ない」ほどなのであ
る0正確に言うと, CPU はバス(アドレスバス,データバス, コントロール バスの三種の
神器)を DMA に明け渡してしまうのである。しかし,ここではハードウェアがど一のこ
一のという話はあまりしないことにする。詳しく勉強したい人は参考文献4である。
まず何よりも DMA が何をするかについて説明しておく。
DMA にできることといえば,後にも先にも,データを CPU より高速に転送/サーチで
きるということ以外にはない ( CPU と同じか,より遅いのならば LDIR なり OUTI なりで
やってしまえばよい)。この「速い」ということは非常に大事なことなのである。これが 一
番はっきりと表面に出てくるのは,8インチドライブや,5インチの 2 HD を使おうとした
ときである。どういうことかというと,これらのディスクのデータ転送速度はやたらと速く
て (2 D , 2 DD の約2倍), 4 MHz の Z 80 では追い付かないのである。具体的には,たとえ
ば読む場合である。 XI では,ディスクからデータを読むということは , FDC (フロッピー
ディスクコントローラ:第9章を参照)に適当なコマンドを与えた後に, FDC のステータ
スを見張っていて, FDC が「データを受け取ってくれ!」と言ってきたら,データを IN 命
令で持ってくるということなのであるが,5インチの倍密度 (2 D や 2 DD がそう)の場合
なら Z 80 でもゆうゆう処理できるのだが,8インチ, 2 HD などになると,お手上げになっ
てしまうのである。人から聞いた話によると8インチ FD の場合 「 Z 80 の 4 MHz ではギリ
ギリ」なのだそうだ。私は実際に, DMA を持っていない MZ -80 B (もちろん CPU は 4 MHz
U8 試験に 出る XI
の Z 80) に8インチドライブをつなごうとして失敗した人を知っている。そういうわけ
で, DMA が XI turbo に付いているのである。
以上のことからも分かるように, DMA とフロッピーディスクとは深い関係にある。しか
し DMA の偉いところは,決して「フロッピーディスクのリード/ライト専用」になってい
ないことである。つまり,単純なデータ転送や,データサーチなら,フロッピーディスク
に関係なくても高速に行なわせることができるのである。実にオイシイ石なのである。
なお, turbo などで 2 HD デイスクを使っている場合は FD の動作がおかしくなること
もあり得るので,以下のサンプルブログラムを使う間は,ディスクは 2 D モードにしてお
くことをお勧めする。
DMA 勿基礎
DMA の基本動作には次の六つがある。
① メモリ-メモリ 転送
これは結局のところブロック転送である。 LDIR , LDDR と基本的には同じだが,
1) 一定以上のバイト数を転送するなら DMA の方が速い。
2) ソースアドレスをインクリメントし,ディスティネーションアドレスをデクリメン
卜する 「順序逆転」 などの 変態 行為を行なわせることができる。
……の点において味がある。
② メモリー I/O 転送
つまり,グラフィック VRAM の書き込み,読み出しである。もちろん,テキスト VRAM
でもよい。矩形領域(画面上の四角)の中を読み出すなどの高等な機能は当然ないが,知
恵を絞れば泉が湧くのである。
③ I/O — I/O 転送
最初に「スクロール」という言葉がひらめいたのなら,貴兄はその筋である。そのほか
にも,青画面—赤画面転送など,一体何に使ったらよいのか悩んでしまう用途も考えられ
る。大容 M RAM ボード ( EMM ) も I / O 空間につながっているので,その方向でも使う価
値がある。
④ メモリサーチ
大きなデータ中のサーチは結構時間がかかってしまうものであるが,かといって DMA
を使うのは大袈裟な気もする。サーチするデータは1バイトだけであるがマスクをかける
こともできる。たとえば,
& H 1?0? ?1? ? (? は無視する)
というパターンをサーチできる。特殊な形式のデータを扱う際には役に立つかも。
(D I/O サーチ
基本的には,やはりグラフィック VRAM のサーチであろうか? しかし「0でないデー
夕を捜せ」などはできないのでいまいちのようである。となればテキスト VRAM のサーチ
ということになるが,たかだか 2 K バイトをサーチするために DMA を使うのは気がひけ
第 8 章 DMA U9
00
07D0
3000
61
0E08
07D0
0E00
0E02
0E05
0E08
0E0A
0E0B
0E0C
0E0D
0E0E
0E11 24
0E12 C2 0E02
0E15 C9
.Z80
•
.PHASE
SIZE
EQU
START :
LD
L00P1 :
LD
LD
LOOP 2:
OUT
INC
DEC
LD
OR
•
JP
t
INC
•
JP
t
•
RET
•
END
0E00H
80*25
H,0 ;counterl
DE f SIZE ; counter2
BC f 3000H
(C) f H
BC
DE
A, D
E ; DE=0 ?
NZ,L00P2
H
NZ f L00P1
それに対して,リスト 8-2 は DMA を使ってみたものである。分かりやすいように特另 IJ
なテクニックは使っていない。これも同じく 256回実行している。本当は DMA では似た
ことを続けて繰り返す場合にはもう少し速くなるのだが,そこまではやっていない《
リスト 8-2 DMA してみたプログラム
.Z80
•
.PHASE
0E020H
07DO
SIZE
•
EQU
80 拿 25
B020
3E
00
•
LD
A,0
AF
;XOR A … COUNTER
E022
F5
LOOP3 :
PUSH
E023
32
E05F
•
LD
(DATAAD) f A
E026
CD
E035
MEIOSI :
CALL
RESDMA
;RESET DMA
E029
21
E050
LD
HL f DMAD
;LOAD TOP OF COMMANDS
E02C
CD
E043
CALL
WDMA
••SEND COMMANDS
る。こうなったら EMM の中でもサーチするしかない。
⑧転送と サーチの 合わせ技
①-②の転送とサーチを組み合わせることが可能なのである。つまり,転送しながらあ
るデータを見つけたら止まれ,というようなことができる。う〜ん何に使おう。
以上が基礎教養である。私はとんでもないことに,この六つの基本動作すべてについて
サンプルプログラムを書こうとしているのである。 DMA という石がどれだけポップでコ
ー フンするものなのかを示したいともくろんでいるのである。
DMA は爆発てあ3
では, DMA を使うということが,どんな雰囲気であるのかを簡単に示しておく。
リスト 8-1 は普通の機械語プログラムで,画面をすべて一つの文字で埋めるプログラム
である。やっぱり,速すぎるので256回実行している。
リスト 8-1 DMA を使わずに
611D3BA32
210E017BC
150 拭験に出る XI
E058 CD
E059 3000
E05B 9A
E05C CF
E05D B3
E05E 87
E05F 00
E02F FI
E030 3C
E031 C2 E022
E034 C9
E035 21 E03C
E038 CD E043
E03B C9
E03C 06
E03D C3 C3 C3
E040 C3 C3 C3
POP AF ;POP COUNTER
INC A ;0 TO 255
JP NZ f LOOP3
RET
RESDMA: LD HL.RESDAT
CALL WDMA
RET
RBSDAT: DEFB 6 ;NUMBER OF COMMAND
DEFB 0C3H f 0C3H f 0C3H
DEFB 0C3H f 0C3H f 0C3H
•WRITE DMA
;HL=TOP OF COMMANDS
WDMA: LD D t (HL)
LD BC f 1F80H : DMA PORT
INC HL
REGWR: INC B
OUT I
DEC D
JP NZ f REGWR
RET
•
DMAD: DEFB
DEFB
S_TOP: DEFW
し iN: DEFW
S_KIND: DEFB
; 00100100 B
D KIND: DEFB
;*0001 1000B
' DEFB
; 1100110 IB
D_TOP: DEFW
DEFB
DEFB
DEFB
DEFB
參
DATAAD: DEFB 0 ;DUMMY
END
0EH ;NUMBER OF COM.
7DH ; (D7=0)AND(D1D0<>00)=WR 0
DATAAD ; SUB0 f l=PORT A TOP ADDR.
SIZE-1 ;LENGTH
24H
: 0??? ?100 = WR1(PORT A MODE)
18H
: 0??? 7000 = WR2 (PORT B MODE)
SKIP WR3
OCDH
: 1?????01=WR4 (WR0 FOR PORT B)
3000H ;PORT B TOP ADDR
9AH ; WR5 READY=HIGH
0CFH ; WR 6 (LOAD)
0B3H ; WR6 (FORCE READY)LOAD)
087H : WR6 (ENABLE DMA)
実行して試してみるにはリスト S -3 である。最初に普通の機械語で組んだものを実行す
る。何かキーを押せば, BEEP 音がして画面がくるくると書き換わる。 CLS の直後は全画
面のアトリビュートが 縦 2倍モードになっていることに 注意。 次にキーを押せば, DMA 版
が走る。明らかに速いことが分かるだろう。最後に同じプログラムを BASIC で組んだもの
も入れておいた。 すばらしく遅い ことは言うまでもない。
リスト 8-3 普通の機械語と DMA を速度比較
100 CLS4
110 DEFINT A-Z
120 CLEAR &HDEEE
130 MEM$(&HE000 f 16)=HEXCHR$( ft 26 00 11 D0 07 01 00 30 ED 61 03IB 7A B3 C2 08 M )
140 NEN$(&HE010 f 6) =HEXCHR$ ( ff E0 24 C2 02 E0 C9”>
150 MEM$(&HE02O f 16)=HEXCHR$( tf 3E 00 F5 32 5F E0 CD 35 E0 2150 E0 CD 43 E0 Fl">
160 MEM$(&HE030 f 16)=HEXCHR$( ft 3C C2 22 E0 C9 213C E0 CD 43 E0 C9 06 C3 C3 C3 M )
170 MEM$(&HE040 f 16)=HEXCHR$( ff C3 C3 C3 56 0180 IF 23 04 ED A315 C2 48 E0 C9 tf )
180 MEM$(&HE050 f 16)=HEXCHR$( ff 0E 7D 5F E0 D0 07 2418 CD 00 30 9A CF B3 87 00 ff )
190 PRINT”NORMAL":GOSUB”SOMEKEY” : BEEP:CALL &HE000:BEEP
200 PRINT”DMA” : GOSUB”SOMEKEY” •• BEEP:CALL &HE020:BEEP
210 PRINT”BASIC” : GOSUB”SOMEKEY”:BEEP
220 FORI=0TO255
230 FORA=&H 3000 TO&H3000+25>80-l : OUTA f I : NEXT
240 NEXT:BEEP
250 END
第 8 章 DMA 151
260 LABE じ 'SOMEKEY"
270 IF INKEY$="”GOTO270
280 RHTURN
リスト 8-2 を見ると分かるだろうが, DMA を動かすには 1 F 8* H 番地にコマンドを
OUT してやればよい。逆に DMA からデータを受け取ることも可能で,そのときは IN 命
令を使う。アドレス中の*は何でもかまわないが,プログラム中では気分よく 1 F 80 H になっ
ている。
ところで,それじゃ DMA に与えることのできるコマンドはたった1バイトだけなの
か?という疑問が起こるはずである。もちろんそんなことはない。コマンドの種類は,
大きく分けて7種類あり,それぞれのコマンドは「1バイト中のこのビツトが立っていた
ら,この種類」というふうに決まっているのである。簡単に言うなら, CPU と DMA の間
であらかじめ決まったフォーマツトで8ビツトパラレルの通信を行なうようなものであ
る。
DMA は霣レ勿てあ3
ではそういう意味も含めて,リス ト 8-4 である。これはオール BASIC で書いてある。要
は, DMA にコマンドを送ってやればよいのであるから,別に機械語を使わなくてもよいの
である。唯一の問題が DMA を使う最大の利点=スピードがなくなってしまうことであ
る。ここではサンブルだからこれでよいのだ
リスト 8-4 オール BASIC で DMA を使ってみる
100 CLEAR&HDFFF
110 POKE&HE000 I ASC( ,, X M ) : ,S 面を埋める文字
120 RESET$=HEXCHR$( M C3 C3 C3 C3 C3 C3 ">:, リセット データ
130 DMA$=RESET$+HEXCHR$("7D 00 E0 CF 07 2418 CD 00 30 9A CF B3 87 ”)
140 GOSUB"SETDMA”
150 END
160 •
170 LABE じ •SETDMA"
180 FORI = lTOLEN(DMA$) : OUT&H1F80 f ASC(MID$(DMAS ,1,1)): NEXT
190 RETURN
ではブログラムの説明に移る。このブログラムは,全画面に 「 XJ を表示するものであ
る。まず最初に CLEAR 命令で領域を確保している。ブログラムでは & HE 000 から&
HEFFF までの 4 K バイトを確保しているが,本当に必要なのはたった1バイトなのであ
った。なぜ1バイトが必要かというと,このブログラムでやっているメモリ— I / O 転送で
はソース(転送元)を アドレスで 指定する必要があるためなのだ。ブログラムでは,その
ソースは & HE 000 に割り当ててあり,そこに ASC rx ") を POKE している。
次が RESET $ = 〜 となって, & HC 3 が6個並んでいる。これは DMA に送るリセットゴ
マンドである0 DMA を初期化するにはとにかく 6個のリセットコマンドを送ってやれ
ば, DMA がどんな状態になっていても成功する。これは最悪の場合であって,本当なら6
個も送る必要はない。しかし安全のために6個送っている。
152 試験に出る XI
次に DMA$ = RESET$ 十〜となっている部分が,主役の コマンド である。その後,
GOSUB ''SETDMA’’ で, DMA$ に入っている & HC 3 〜 & H 87 までの20個の命令を DMA
に送っている。
そこで肩慣らしにリスト 8-4 に出ている DMA のコマンドの解説を行なう。
① 概要
DMA へのコマンドは,大きく分けて7種類ある。それぞれ, WR 0 〜 WR 6 と呼ばれてい
る 0 WR とはライトレジスタ (Write Register ) という意味で,早い話, DMA へコマンド
を送るというのは,この七つのレジスタに値を害き込むこと,と解釈すればよい。なお,
それぞれの WR の下にはサブレジスタというものがあり,多少複雑になっているが,別に
難しいものではない。それぞれのコマンドの分類の仕方だけを図 8-1 に示す。全部で7種
類なのだから左端(もしくは右端)の3ビットで判別できるようにすればいいようなもの
だが,きっとそこには Zilog なりの複雑な事情というものが存在するのであろう。さらに細
かな意味や内容を知りたい場合は図 8-2 〜 8-9 を見ていただきたい。
② C 3„ = & H 1 100001 1
図 8-1 と比べれば, WR 6 であることが分かるだろう。意味は前述のように RESET であ
る。
③ 7 D „ = & B 01111101
MSB (左端)が0 で, 右端の二つが〇〇 でない から WR 0 である。そこで 図 8-2 を見
る。 D !, D 0 はデータの 処理形式を指定す る。ここでは 「01」だから ト ランス ファー (転送)
である。 D 2 (=1) はデータの 転送方向で ある。 DMA は 二つの ポート (A と B ) を持っ
図 8-1 DMA ライトレジスタ分類早見表
D ;
d 6
D s
d 4
d 3
D ?
D ,
D 0
WR 0
0
?
•
?
?
7
?
#
L
1
〇〇でない—
i -
1
WR 1
□
D
D
D
D
D
□
□
■
■
■
■
■
■
WR 2
□
D
D
D
D
□
□
□
WR 3 I 1 I ? ? ? ? ? 0 〇
D
■
1
bud
□
D
_
■
D
□
D
dbd
D
□
WR 6 1? ? ? ? ?11
第8章 DMA 153
ていて,ソース(転送元)とディスティネーション(転送先)に割り当てるのである〇 A と
B の間には,別にどうという違いはないので,迷う必要はない。ここでは A — B の方向に
している〇 D 6 , D 5 , D 4 , D 3 はポート A の開始アドレスと,ブロックレングス(処理バイ
卜数 一 1) を設定するかどうかのフラグになっている ( Z 80 DMA の用語ではボインタビッ
卜という)。1であれば新しく設定するということになる。0の場合は,設定しないという
ことであり,その場合は以前に設定されたものが使われることになる。図 8-2 からも分か
るように,それぞれを上位,下位に分けて設定するようになっていて,新しく設定すると
なれば, LSB (右の方)から指定した順に 1 F 80„ に OUT してやればよい。ここでは4ビッ
卜とも1であるから,全部指定することになる。つまり,00„, E 0„, CF „, 07„が,それぞ
れサブレジスタの〇〜3に設定される。処理バイト数が 07 CF „ = 80 X 25-1 であることに
注意01引いておくのだ。念のために言うが,もしブロックレングスの下位を設定しない
場合は, 2 D „ = & HB 01011101 の後に, 00„, E 0„, 07„とすればよい。
④ 24 h = & B 00100100
図 8-1 より WR 1 である。 D 3 により,ポート A をメモリにするか, I / O にするかを決定
する(ポー ト B は WR 2 で 決める)。 D s , D 4 は1バイ ト 転送した後,ポー ト A のアドレス
をどう変えるかを指定するものである。図 8-3 にあるように, 一 1,+1,固定(変化させ
ない)の三つの方式を指定できる。ここでは,テキスト VRAM を1種類の文字で埋めるの
であるから,ソースであるポー ト A のアドレスは E 000„ に固定することになる。10,11ど
ちらでもよいが,縁起物だから10にしてある。次に D 6 であるが,これはポート A へのア
図 8-2 WRO
1 ■ ■ ■
WR 0
D , D & D $ Di D ; Di D 。
0
r
ベース.レジスタ
■
(
]
0 0 使用しない
01 転送
10 サーチ
11 サーチ転送
) ポート B — ♦ポート A
1 ボート A — ポート B
_
—
ボート A 開始アドレス
1 ■
(下位バイト)
ボート A 開始アドレス
i
(上位バイト)
ブロック長 *
1
(下位バイト) t 実際の転送
ブロック長 バィト数-1
(上位バイト) j
154 試験に出る XI
クセスのタイミングを変える場合に 1 にする。その場合,次に1バイトを送ってやればサ
ブレジ スタに値を設定できる。ところが どっこい, turbo ではこの部分は使えないのであ
る。使えたなら,さらに転送速度を上げることができるのであるが仕方がない。
⑤ 18„ = & B 0001 1000
WR 2 である。これは指定の対象がポート B になった点を除いて WR 1 と同じ使い方で
ある。テキスト VRAM へ書き込むのだから,ポート B は I / O で,インクリメントにして
ぁる。
(D CDh = & B 11001110
WR 4 である。 WR 3 はサーチ用なので,ここでは抜かしてある。 D 3 , D 2 がポート B 開始
アドレスの指定0ここでは, 00 H , 30„がそうである。 D 6 , D 5 が転送モードの指定である。そ
れぞれの転送モードの詳細は次のとおり。
バイトモード: DMA は1バイト処理するたびに CPU にバスを返す。しかし, WR 0 で指
定したブロックレングスだけのバイト数を処理し終わってなく,かつレディ信号(次に
WR 5 で説明する)が有効であれば,その直後に再びバスを要求するので, CPU は1マシ
ンサイクルしか命令を実行できない。早い話が DMA と CPU は交代でバスを使うことに
なる。 turbo では DMA を使ってフロッピーディスクにアクセスする場合,このモードを使
っている(第9章を参照のこと)。
バーストモード: DMA はレディ信号が有効である間は CPU にバスを返さず,ブログラム
図 8-3 WR 1
WR 1
D7 D $ D $ D4 D3 D ; D | Do
0
1
0
0
0 メモリ
1 I/O
ベース.レジスタ
0 ボート A アドレス•デクリメント
1ボート A アドレス•インクリメント
0 ボート A アドレス可変
1ボート A アドレス固定
0 0 ボート A タイミング制御
0 0 サイクル長 =4
01 サイクル長 =3
10サイクル長=2
11使用しない
0 I で^は%サイクル早く終了
_ 0は%サイクル早く終了
0 RD は%サイクル早く終了
0 _は%サイクル早く終了
turbo では
使えない
第8章 DMA 155
された処理が終わるまで動作を行ない続ける。レディ信号が無効になった場合は CPU に
バスを返すが,再び有効になると,またバスを要求する。この章のサンブルはすべてこの
モードを使っている。
連統(コンティニュアス)モード: これは DMA が我儘を通すモードで, DMA はプログラ
ミングされたとおりの処理を終わるまで,レディ信号が無効であっても CPU にバスを返
さない。つまり CPU は DMA が処理を終えるまで,何もできないことになる。特に素早い
応答が要求されている場合に,このモードが使われる。
认は割り込み制御バイトと呼ばれるサブレジスタを指すものである0サンブルでは使つ
図 8-4 WR2
WR 2
D 7 De D$ D 4 D 3 D ; D| Dq
0
0
0
0
ベース•レジスタ
0
0
メモリ
1 I/O
0 ポート B アドレス•デクリメン
1ボート B アドレス•インクリメ
ボート B アドレス可変
ポート B アドレス固定
〇
0
ボート B タイミング制御
0 0 サイクル長= 4
01 サイクル長=3
10 サイクル長= 2
11 使用しない
0 R 5 RQ は%サイクル早く終了
_ は%サイクル早く終了
0丽は%サイクル早く終了
0灰^は%サイクル早く終了
turbo では
使えない
図 8-5 WR3
WR3
D? 〇 6 Ds D« D 3 D ; Di Do
156 試験に出る XI
ていないが一応説明しておく。まず,パルス発生(ビット 2) は turbo では使えない 0 これ
は外部デバイスにパルスを送るものであるから, turbo にとっては必要なものではない。
次にインタラプト•オン(マッチ,エンド•オブ•ブロック,レディ)の三つである
が,これはそれぞれの条件のときに割り込みを起こせということ。ステータス•アフエク
ツ•べクトルというのは割り込みべクトルを,割り込み要因ごとに変化させるかどうかの
フラグである。パルス制御バイトは,パルス発生を使えないのであるから turbo では意味
がない。割り込みべクトルは DMA から CPU に割り込みをかけるときのべクトルの下位
アドレスを指定するもの。モード2の割り込みをきちんと理解してからいじるように(割
図 8-6 WR 4
WR 4
D ? D $ Ds D « D3 D ? Di Do
0 ORDY 割り込み
01 一致割り込み
10 エンド•オブ•ブロック割り込み
11 エンド•オブ•ブロックー致割り込み
図 8-7 WR 5
WR5
D7 Ds Ds D4 Da Dz Di Do
1
上
0
1
0
ベース.レジスタ
0 レディは“ Low "
1 レディは“ High ”
0 CE ■のみ
1 CE / waiT マルチブレクス
0 エンド•オブ•ブロックでストップ
1 エンド•オブ•ブロックで自動繰り返し
第8 章 DMA 157
り込みに関しては第 4 章を参照のこと)。
⑦ 9 A h = & B 10011010
WR 5 である。まず D 3 であるが, DMA には RDY という端子があって,そこへ入ってく
る信号をレディ信号という。 D 3 はレディ信号が High のとき有効にするか, Low のときに
有効にするかの指定である。 turbo では通常はこの信号は High になっているので,このビ
ットは1にしておく。逆に, FDC からデータ要求が来ると Low になるので,ディスクの読
み書きをする場合は0にして, Low を有効とする。 D 4 は d / WXIT の使い方である。 turbo
ではこのビットを1にして WXIT を受け付けるようにすること。 D s は オート リスタート
の指定だが,これは0にして「エンド •オブ •ブロックで終決」にする。つまり,ブロッ
クレングス分の処理を終えたらバスを CPU に返して止まるということである。もしオー
トリスタートにしたなら,レディ信号が有効である限り再スタートするので,止まってく
れないことになる《
図 8-8 リードレジスタの内容
158 拭験に出る XI
イネーブルコ
開始する。こ
。このコマンドを受け取ると, DMA は直ちにバス要求を出し動作を
,ンド以外のコマンドは • すべて DMA をディセーブルする_
•バイト初期再設定コマンド。ステータス•バイトのビット4(一致成立)お
ド•オブ•ブロック)を初期化する。
割り込みリセットおよびデ
8080などが RETI の代わり t
# 〇 Z 80 を使つている turbo には関係ない〇
I 充み出しシーケンス起動コマンド。このコマンドが送られると,マスク設定コマンド (B
B „) で指定されたレジスタを順番に読み出せる。リードレジスタの図解を参照。
^- - ^ _ ■
割り込みイネーブルコマンド。電源投入時, DMA は割り込みディセーブル状態で起動す
るので, DMA の割り込み機能を使用するときはこのコマンドを送る。このコマンドをセ
ツトした後,割り込み条件が発生すると, DMA は CPU に対して剳り込み要求を出し統
けるので,割り込み処理ルーチンのはじめの方で割り込みディセーブルコマンド ( AF h )
を送ること。割り込み処理終了後.ふたたび割り込みイネーブルコマンドを送る前に,割
り込み条件をリセツトするためにステータスバイト初期再投定コマンド (8 B h ) を送る必
要がある。
割り込みディセーブルコマンド。 DMA の割り込み処理ルーチンのはじめの方にこのコ
マンドが必要。そのルーチンの終わりには,ステータス.バイト初期再設定コマンド (8
B „) と割り込みイネーブルコマンド ( AB H ) が必要
マンドによって, RDY 信号は強制的
ドは,ロー ドコマン K(CFm) によつ
つてやる必要がある。また,バイト
RETI 後イネーブルコマンド。インタラブト•オン•レディ•モードのときのみ使用される
( WR 4, 割り込み制御バイトのビット6)。このモードで RDY 信号がアクティブになると
DMA は割り込み要求を出す。割り込み処理後, DMA にバス要求を出させたい場合 , RETI
後イネーブルコマンド ( B 7„). DMA イネーブルコマンド(87„)を送った後 • RETI 命令を
実行すればよい。
マンド。このコマンドに統く1バイトデータは • S 充み出しマスク
5>。マスクでセツトされた I 売み出しレジスタの|充み出しシーケン
:つて起動する。
卜)だけを i 売む場合
卜统み出し
• 〇 電源投入時や DMA のブログラム打ち切り時に使用される
WR 1 のボート A 可変タイミングを標準 Z 80 タイ
この機能がある。ただし, turbo では可変タイ
WR 2 のボート B 可変タイミングのリセット(同上 ) c
コマンド。バイトカウンタをクリアするが,両ボートのアドレスカウン
こ現状の値を保持する。
⑧ CF H = & B 11001 川
WR 6 である。 WR 6 はビットごとに意味を持つわけではない 0 CF h はロードコマンドであ
るが,これは設定された値をワーク用のカウンタにロードするものである。早い話が,「よ
一い,どん!」の「よ一い」である。
⑧ B 3 h =& B 10110011
強制レディコマンド。つまり, RDY 信号を常に有効と見なせ,というコマンド 〇 WR 5 の
9 A „ で High を有効にしているから,本当は必要ない。しかし, RDY 信号が関係なく
て,とにかくブロックレングス分の処理をさせたい場合には入れておく方がよい。「よ 一
い,どん!」の「よ一い」と「どん!」の間に,「途中で止まるな」と耳元にささやくよ 一
なものである。
⑱ 87„ = & B 100001 1 1
WR 6 で,イネーブルコマンド。要するに「どん!」で, DMA はこのコマンドを受け取
ると,それっとばかりに動き出す。 DMA が動き出すと,バスの管理は CPU を離れて DMA
に移る0こうなると CPU は命令を読み出すこと(つまりフェッチ)もできない0すなわち
金縛りにあうわけである。だから Z 80 のブログラムとしては,続けて何事もなかったかの
ように「転送直後にすること」が書かれていればよいことになる。
以上がこのサンブルの解説である。はっきり言って異常に面倒臭いが,それは最初のう
ちだけで,一度コマンド列を作ってしまえば,やることを変えるのに,それほど手間はか
からない。
そこで,基本的なバリエーションを示してしまえばよい,というわけで,突如としてサ
ンブルブログラムが山津波を起こすのであった。
A ) リスト 8-5 (正しい手抜き法)
DMA では,設定し直さなければ,以前に設定したライトレジスタとサブレジスタを使う
ことになる。つまり,似たような処理を続けて DMA に行なわせる場合,当然レジスタの
設定も似てくるから,いちいち再設定しなくてもよいレジスタが出てくる0リスト 8-5
は,そこ極端な例で, WR 6 以外は同じままでよいので, 150 〜 190 行の間のループではソー
スへ ASCII コードを POKE した後, CF H = 口ード, B 3 H = 強制 レディ, 87„ =イネーブルだ
けを DMA に送っている0変化しているのはソースアドレスではなく,ソースアドレスの
内容であるから WR 0 のポート A 開始ァドレスは再設定する必要がない。やっていること
は,リスト 8-3 と同じく,〇〜 255 の ASCII コードの文字を画面中に書いているだけであ
る。ループの中では DMA に送るのは 3 バイト(本当は B 3„ も抜かしてよい)だけになっ
たので,結構速くなっている。
リスト8 5正しい手抜き法
100 CLEAR&HDFFF
110 RESET$=HEXCHR$( M C3 C3 C3 C3 C3 C3 M )
120 DMA$ = RESET$«*-HEXCHR$ ( M 7D 00 E0 D0 07 2418 CD 00 30 9A")
130 GOSUB"SETDMA"
160 試験に出る XI
C ) リス ト 8-7 (メモリ— I / O )
「 CLS 4」 と大体同じことをするブログラムである。具体的には,テキスト VRAM へ
32(スペースの ASCII コード),アトリビュートへ7,漢字 VRAM とグラフィック VRAM
へ0を書き込む0ただしグラフィックの方はバンク〇か1,どちらか一方,アクセス可能
な状態になっているバンクだけをクリアする。気になったので100回実行して 「CLS 4」
と速度を比べてみた0約2倍の速度であった。140行の HEXCHR $ の中は機械語ルーチン
である0ソースリストは リス ト 8-8 である0 OUTI を使ったテクニックで少しでも速くし
ようということをもくろんでいる(本当は JR を JP にするともっと速くなる)。 USR 0
( DMA $) を実行すると, DE レジスタに DMA $ の内容へのポインタ, B レジスタに文字列
の長さが入って E 000 H にサブルーチンコールするのである。また,230行の0, 32, 7,は
転送するデータなので, 0 — 2 などのように変えると5分間ぐらいは楽しめるであろう
(100回ループは消すんだよ)。
リスト 8-7 「 CLS 4」 モドキ
100 DEFINT A-Z
110 INIT:KLIST0:CONSOLE0,25
第8章 DMA 161
E000
E001
E002
E005
E006
E008
E009
E00B
• Z80
•PHASE 0E000H ; 0R ANY PLACE
; DE=ADDRESS TO DATA,B=COUNTER
LD A,B
EX DE,HL ;HL POINTS DATA
LD BC f 1F80H ;DMA ADDRESS
LOOP : INC B
OUT I
DEC A
JR NZ,LOOP
* RET
END
100
110
120
130
140
150
160
170
180
190
200
210
220
CLS4
PRINT" 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmn”
PRINTSTRING$( 160," >
RESET$=HEXCHR$("C3 C3 C3 C3 C3 C3 ”>:, リセット データ
I
’行を替えて同*
DMA$=RESET$+HEXCHR$( M 7D 00 30 4F 00 1C 18 CD 50 30 9A CF B3
’同じ行で逆 m
1 DMA$=RESET$+HEXCHR$( M 7D 00 30 4F 00 1C 08 CD 4F 30 9A CF B3
’行を替えて逆頻
, DMA$=RESET*+HEXCHR$("7D 00 30 4F 00 1C 08 CD 9F 30 9A CF B3
t
GOSUB m SETDMA m
87
87
87
D) リスト 8-9 ( I/O — I / O )
DMA のありがたみは,やはり LDIR が使えず,なおかつポインタとして BC レジスタし
か使えない I / O へのアクセス時に七色するのである。最初はテキスト VRAM — テキスト
VRAM の転送である。110行にあるどうしようもない文字列を0行目にプリントした
後,同順,逆順に転送する。アトリビュートや漢字 VRAM には触っていないので,何かに
使おうとする場合は注意が必要である。3とおりのコマンド列を作っておいたから,「’」
( REM ) を消して使っていただきたい。特に180行の「同じ行内へ逆順に転送する」という
やつは,ソースとディスティネーシヨンが重なるとどうなるかという意味も含んでいる(結
果は別にどうということもないが)。
リスト 8-9 I / O — 1/0(文字列)転送
卜 8-8
, SETDMA"
120 CLEAR&HDFFF
130 DEFUSR0=&HE000
140 MEM$(&HE000 f 12)=HEXCHR$( M 78 EB 0180 IF 04 ED A3 3D 20 FA C9 M )
150 ,機械語ルーチンを作って 速く したのだ。
160 RESET$ = HEXCHR$( M C3 C3 C3 C3 C3 C3 •• レ •’ リセット データ
170 DMA$=RESET$+HEXCHR$( m 7D 20 E0 CF C7 2418 CD 00 38 9A CF 87 M )
180 ,漢字 VRAM とグラフィック VRAM をクリア。
190 DMA$ = DMA$+ HEXCHR$ (•• 4D 21 07 C9 30 CF 87 M )
200 ,テキスト VRAM を 32 ( スペース)に 0
210 DMA$=DMA$+ HEXCHR$("0D 22 C9 28 CF 87 M )
220 ,アトリビュートを 7 ( 白)に。
230 POKE&HE020,0,32, 7: ,それぞれのデ - 夕です。
240 TIME=0 : FORK=1TO100 : D$=USR0(DMA$) : NEXT : T1=T1ME
250 TIME=0 : FORK=1TO100 : CLS4 : NEXT : T2=TIME
260 PRINTT1 f T2
270 END
8 B 14 D D 0 9
7 E 0 0 E 3 2 c
試験に出る XI
230 LOCATE 0,10
240 END
250 1
260 LABEL M SETDMA"
270 FORI = 1T0LEN(DMAS) : OUT&H1F80 f ASC(MID$(DMAS,I f 1)) : NEXT
280 RETURN
E ) リスト 8-10 ( I/O — I / O )
人呼んで「回転星」という。このプログラムは EMM (大容量 RAM ボード)が必要だ
から,持っていない人は指をくわえて見ていていただきたい。
このブログラムが何をしているかというと, EMM - G-RAM の間でデータ転送をして
いるのである。グラフイックデータはモノクロで1ページ当たり 640 X 200 = 16 K バイトで
ある, EMM の容 M は 320 K バイトだから,計算すれば320+16 = 20画面分が1枚の EMM
に入ってしまう。8色なら320/48 = 6.66……であるから6画面分。640 X 400ならばその半
分の3画面分である。
リスト 8-10 回転星
100 WIDTH80, 25 : INIT : KLIST0 : CLS4
110 OUT&HD00 f 0 : OUT&HD0 1 f 0 : OUT&HD02 f 0 : ,EMM の内部ァドレスを 0 にする。
120 •デ麵夕を EMM に送りこむ•(20¢分)
130 S= 360/20/5: FORJ=1TO20
140 FOLY(320 f 100 ) f 90 f 4 f 144 f 90^JtS f 720^90^J>S : •星形を書 く
150 PAINT(0 f 0) f 2 f 4 : PAINT(320 t 100) 9 1 9 2
160 GOSUB"EMMW ••: CLS4
170 NEXT:BEEP
180 1
190 INIT : CLS4 : F=0 : Q=0 : B=0
200 OUT&HD00 f 0 : OUT&HD01 f 0 : OUT&HD02 f 0 : ,EMM の内部アドレスを 0 にする •
210 Q=( (Q-f 1 )AND7) : B=( (Q4^1 )AND7)
220 FORJ=1TO20
230 IF 0 GOSUB ff EMMR tf ELSE GOSUB"EMMR-2” : •次々と GRAM へ 転送する •
240 NEXT:GOTO 200
250 END
260 1
270 LABEL m EMMW :, GRAM から EMM へ 転送す る •
280 DMA$ = HEXCHR$( ff C3C3C3 C3 C3 C3 7D 03 0D FF 3F 2C 18 CD 00 40 9A CF 01 CF 87” >
290 GOSUB M SETDMA f#
300 RETURN
310 1
320 LABEL" EMMR ff EMM から GRAM へ 転送する.
330 DMA$ = HEXCHR$( M C3 C3 C3 C3 C3 C3 7D 03 0D FF 3F 2C 18 CD 00 40 9A CF B3 87")
340 GOSUB tf SETDMA ft
350 RETURN
360 1
370 LABEL’EMMR-2": ’fl 面スワッビングも使いながら EMM から GRAM へ 転送する •
380 IF F THEN 420
390 DMA$ = HEXCHR$( ff C3 C3 C3 C3 C3 C3 7D 03 0D FF 3F 2C 18 CD 00 40 9A CF B3 87" >
400 GOSUB ff SETDMA M : PALET® B 9 Q t B f Q 9 B 9 B 9 B f B
410 GOTO 440
420 DMA$ = HEXCHR$( ,f C3 C3 C3 C3 C3 C3 7D 03 0D FF 3F 2C 18 CD 00 80 9A CF B3 87 ff )
430 GOSUB tf SETDMA tf : PALET® B f B 9 Q t Q f B 9 B 9 B 9 B
440 F=(F=0) : RETURN
450 1
460 LABBL ,f SETDMA ff
470 FOR 1 =1 TO LEN(DMA$):OUT &H1F80 f ASC(MID$(DMAS•I•1)) : NEXT
480 RETURN
このブログラムは DMA を使い, EMM から G-RAM へデータを転送することによ
り,一気にアニメーションしてしまおうというものである。ここでは星を回しているだけ
だが,どんな図形だろうと同じ手間だから,結構面白いことができるはずである。
というところで,リスト 8-10 の解説を行なう。130〜170行が星型のグラフィックを描
き, EMM へ送り込むルーチンである 〇 EMM の内部アドレスは自動的にインクリメントす
るから,110行と200行で EMM の内部アドレスを設定するだけで済む。
第8章 DMA 163
さて,実はこのサンブルは,
とっても大事なのである。
というのは, DMA ではディスティネーションが 固定アドレスの場合は特別な操作が 必
要なのである。 EMM へのデータ書き込みは,固定アドレスへの転送だから,これにひっか
かるのである。具体的には,ディスティネーションに使用されるポート(この場合はポー
卜 A ) に実際にアドレスがロードされるのは,最初の増減(インクリメント/デクリメン
卜)が行なわれたときなのだ。だからアドレス固定の場合は死ぬまでロードされない〇そ
のために,少々手間をかけてやる必要がある。早い話が,とりあえず一度ポート A を ソー
スに指定してから CF h (口ード コマンド)を送ってやるのである。ソースの方は,ロード
コマンドが送られると,その時点でちゃんとアドレスがロードされるから 0 K o その直後に
「やっぱりポート A はディスティネーションにするね」と,ひっくり返すのである 0 280行
にある HEXCHR $ の中の後ろの方の rCF 01 J がその部分である。 01 H ( WR 0 : B — A 指
定)が鍵なのである。その後は 「CF 87」で再ロード, DMA イネ ー ブルで走ってくれる。
次に230行の 「IF 〇〜」というやつであるが,これは2とおり用意した EMM — G -
RAM 転送のうち,どちらを選ぶかの分岐点になっている。 GOSUB 、' EMMR " の方がシ
ンプルだが,転送している様子が見えてしまうのであまり美しくない 0 そこで'' EMMR -
2" では青画面(もちろん色はパレットで変えてある)を表示しつつ,赤画面へ転送し,転
送後青画面を引っ込めて,赤画面を表示,次は赤画面と青画面の役割を入れ替えて同じこ
とを繰り返す,ということをやっている。どちらもそれほど速くないが,これは DMA の
せいではなく,460行からのサブルーチン、、 SETDMA " がトロいのである 0 リスト 8-8 の
機械語サブルーチンを使えばほぼ2倍の速度になる。 リスト 8-11, 8-12 に DMA を使わず
に CPU がシコシコと転送するブログラムも載せておくので, turbo ユーザーでない人も試
して欲しい。ただし NEW BASIC ( CZ -8 F 01 V 2.0) でないとペイントにいらだつと思わ
れるので覚悟するよ一に。
なお,リスト 8-11 で USRO , USR 1 に文字列を渡しているのは, & H 8000が実数型にな
ってしまうためである 0 さらに補足すると,リスト 8-12 のそれぞれの先頭にある 「CP 3」
は A レジスタが渡された変数のタイプを持っているので,それをチェックしているのであ
る。文字列型以外であれば,タイプミスマッチのエラーが発生するようにしてある 0 肝心
の速度の比較であるが,リスト 8-10 とたいして変わらないようである。
$
リスト 8-11 DMA を使わない回転星
100 CLEAR&HDFFF
110 DEFUSR0=&HE000 : DEFUSR 1 =&HE030
120 MEM$(&HE000 f 16)=HEXCHR$( ff FE 03 28 04 3E 0D DD E9 EB 46 23 4E 21 00 40 D9 M )
130 MEM$(&HE010 f 16)=HEXCHR$( ff 01 03 0D D9 ED 78 03 D9 ED 79 D9 2B 7C B5 C2 14”}
140 MEM$(&HE020 f 2) =HEXCHR$ (” E0 C9 M )
150 MEM$(&HE030 f 16)=HEXCHR$( tf FE 03 28 04 3E 0D DD E9 EB 46 23 4E D9 21 00 40 M )
160 MEM$(&HEO40 f 16)=HEXCHR$( H 01 03 0D ED 78 D9 ED 79 03 D9 2B 7C B5 C2 43 E0 ff )
170 MEN$(&HE050 9 1)=HEXCHR$( tf C9 tf )
180 WIDTH80 : INIT : CLS4
190 OUT&HD00 f 0 : OUT&HD0 1 f 0 : OUT&HD02 f 0 :, EMM の内部アドレスを 0 にする .
200 • データを EMM に送りこむ • (20 面分〉
210 S=360/20/5 : FORJ=lTO20
220 POLY(320 f 100) • 90 • 4 • 144 • 90+ J*S•720+90+J 拿 S : 1 星形を害く
230 PAINT(0 f 0) f 2 f 4 : PAINT(320 f 100) f 1,2
240 GOSUB ff EMMW-NM ff : CLS4
164 拭験に出る XI
4000
0003
E008
E009
E00A
E00B
E00C
E00F
E0!0
038 EB
E039 46
03A 23
E03B 4E
E030 FE 03
032 28 04
E034 3E 0D
036 DD E9
E022
021 C9
E013
E014
E016
E017
E018
E01A
B01B
E01C
01D
E01E
D9
ED 78
03
D9
ED 79
D9
2B
7C
B5
C2 E014
E000 FE 03
E002 28 04
E004 3E 0D
E006 DD E9
250 NEXT:BEEP
260 1
270 INIT : CLS4 : F=0 : Q=0 : B=0
280 OUT&HD00 f 0 : OUT&HD0 1 f 0 : OUT&HD02 f 0 : , EMM の内部アドレスを 0 にする0
290 Q=((Q+l)AND7) : B=((Q^ 1 )AND7)
300 FORJ=1TO20
310 IF 0 GOSUB ff EMMR-NM ff ELSE GOSUB"EMMR-NM-2” : •次々 と G R A M へ 送する 0
320 NEXT:GOTO 280
330 END
340 1
350 LABEL M EMMW-NM ft :,GRAM から EMM へ転送する.
360 D$=USR0 ( HEXCHRS ( M 400O ft ))
370 RETURN
380 1
390 LABEL ft EMMR-NM tf EMM から GRAM へ転送する0
400 D$=USR1 (HEXCHR$( f, 4000 ff ))
410 RETURN
420 1
430 LABEL #t EMMR-NM-2 ••: ,由! 由•スワッビングも使いながら EMM から GRAM へ転送する 0
440 IF F THEN 480
450 D$ = USR1 (HEXCHRS ( ff 4000"))
460 PA し ET0 , B : PALET1 t Q : PALET2 f B : PALET3 f Q
470 GOTO 500
480 D$=USR1 (HEXCHR$( tf 8000 ft ))
490 PALETO f B : PALET1 f B : PALET2 f Q : PALET3 f Q
500 F=(F=0) : RETURN
B 6 3 E 191
E 4 2 4 2 D 0
第 8 章 DMA 165
E050 C9
E03C D9
E03D 214000
E040 01 0D03
F ) リスト 8-13, 8-14 (テキストスクロール)
別に言うことはないが,このプログラムを走らせると,画面に表示されている漢字が 一
瞬化ける。これは三つの転送(テキスト VRAM , アトリビュート,漢字 VRAM ) の間に
時間差があるため。つまり '' SETDMA " が遅いからである。
リスト 8-13 テキストス クロール アップ
G ) リスト 8-15 (上8ドットグラフィックスクロール)
これは8ドット分グラフィックを上へスクロールさせるブログラムである
4050 h 〜477 F h —4000 h 〜472 F h
8 9 0
7 7 E
D9D39BC52
EDE0D27BC
35689 ABCD
444444444
000000000
EEEEEEEEE
166 拭験に出る XI
4850 h 〜 4 F 7 F „ —4800 h 〜 4 F 2 F „
RESET$=HEXCHR$ 《 ”C3 C3 C3
’ 靑 H 面
DMA$ = RESET$ +HEXCHRS ( f, 7D
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
’ 赤曲 i 面
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
’緑 fl 面
DMA$ = DMA $、
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
DMA$=DMA$
FORK=0TO20
END
+HEXCHR$《"15
♦HEXCHR$("15
♦HEXCHR$("15
+HEXCHR$("15
+HEXCHR$("15
+HEXCHR$(”15
+HEXCHR$("15
+HEXCHR$(”15
♦ HEXCHR$「15
+HEXCHR$( M 15
+HEXCHR$("15
+ HEXCHR$(.,15
♦HEXCHR$("15
♦HEXCHR$("15
+HEXCHR$<"15
+HEXCHR$("15
+HEXCHR$( M 15
+HEXCHR$( M 15
+HEXCHR$("15
+HEXCHR$("15
+HEXCHR$("15
♦HEXCHR$("15
+HEXCHR$< M 15
D$=USR0(DMA$)
DEFINT A-Z
CLEAR&HDFFF
DEFUSR0=&HE000
MEM$(&HE000 f 12)=HEXCHR$( M 78 EB 0180 IF 04 ED A3 3D 20 FA C9”>
INIT : CLS4 : CIRCLE(320 f 100) ,60,6
PAINT(320 f 100) , &H 26,6
SYMBOL <282, 100) , •• 朝です " , 2,2 , 7 , 0 • PRESET
H ) リスト 8-16 ( 左 8 ドットグラフィックスクロール)
400 1 H 〜7 FFF H — 400 0 H 〜7 FFE H
800 1 h 〜 BFFFh — 800 Oh 〜 BFFEh
COOIh 〜 FFFFh — COOOh 〜 FFFEh
の 3 回ブロック転送をしている。考えられる限りセコいので,80回 (640 ドット)左ヘス
クロールすると8ドット分上へ上がってしまう。これについては,普通の機械語でも試し
第 8 章 DMA 167
7850„〜7 F 7 F „ —7800„〜7 F 2 F „
という具合に8回ブロック転送を実行している。これは XI のグラフィックの座標とアド
レスの関係からこのようになっているのである。このブログラムでは Y 座標が192〜199
に当たる下の方の8ライン分はそのまま残るので,140行のサークル命令の半径を95ぐ
らいにするとゴミが出る。
リスト 8-15 上 8 ドットグラフイックスクロ-ル
\/ )/ )/ \/ \/ \/ \/ \/
77777777
88888888
FFFFFFFF
CCCCCCCC
AAAAAAAA
99999999
08080808
8899AABB
\/ \/ \/ \/ \/ \/
77777777
88888888
夕
■
デ
卜
ヅ
セ
77777777
88888888
FFFFFFFF
CCCCCCCC
AAAAAAAA
99999999
0 8 0 8 0 8 O 8
44556677
0
0
D 9999999
CCCCCCCC
8
1
99999999
CCCCCCCC
FFFFFFFF
CCCCCCCC
AAAAAAAA
99999999
08080808
CCDDEEFF
99999999
CCCCCCCC
c
3
c
3
c
3
c
7
0
F
0 8
4 4
0 8 0 8 0 8
5 5 6 6 7 7
0
5
08080808
8899AABB
0 8 0 8 0 8
c c D D E E
0 8 T
F F X
E
N
00000000000000000000000000000000000000
01234567890123456789012345678901234567
11111111112222222222333333333344444444
A を使わずにグ
8-17
PRI
00 DEFINT A-Z
10 CLEAR&HDFFF
20 DEFUSR0=&HE000 : DEFUSR 1 =&HE 100
30 MEM$(&HE000 f 12 )=HEXCHR$( if 78 EB 0180 IF 04 ED A3 3D 20 FA C9">
40 INIT : CLS4 : CIRCLB(320 f 100) t 60 9 6
50 PAINT(320 f 100) f &H26 f 6
60 SYMBOL(266 f 100} ," R 常です •• • 2 • 2 , 7 , 0 , PRESET
70 1
80 RESET$ = HEXCHR$( lf C3 C3 C3 C3 C3 C3 ff ) : f リセット デ-夕
90 •育 《 面
00 DMA$ = RESET$ + HEXCHR$( M 7D 0140 FE 3F 1C 18 CD 00 40 9A CF 87” >
10 •赤 19 面
20 DMA$ = DMA$ ♦HEXCHRS ( ff 15 80 C9 80 9A CF 87 M )
30 ®
40 DMA$ = DMA$ ♦HEXCHRS ( #t 15 CO C9 C0 9A CF 87 #t )
50 TIME=0 : FORK=0TO80 : D$=USR0(DMAS) : NEXT : PRINT M BY DMA =";TIME
60 1
70 MEM$ (&HE 100,16) =HEXCHR$ ( f# FE 02 28 04 3E 0D DD E9 7E B7 C8 57 01 00 40 CD
280 MEM$(&HE110 f 16) =HEXCHR$ ( tf 23 El 01 00 80 CD 23 El 01 00 C0 CD 23 El15 C2
90 MEM$ (&HE 120,16) =HEXCHR$ ( f# 0C El C9 78 D9 47 0E 0121 FE 3F ED 78 03 D9 ED
( M 79 03 D9 2B 7C B5 C2 2B El D9 C9">
••NOT BY DMA = ft : TIME
て速度を比べてみた。270行からがそうである。 USR 1 に「8ドット左へスクロールする回
数」を渡せばよい0サンプル中では80を渡してある。機械語部分のソースは リスト 8-17
である。本当はありとあらゆる汚い手を使って高速化してみたかったのだが,読みづらく
なるので避けたのである0もっとも,このサンブルのように, BC と B ' C をソースとディス
ティネーシヨンに割り当てるのが一番速いと思う。
リスト 8-16 左8ドットグラフィックスクロール
3 4 5 6 8 B D E
22222 2 2 2
11111 111
E E E E E E E H
E139 D9 EXX
E13A C9 RET
• END
ET
MA
BYTE
NTER
00 DEFINT A-Z
10 CLEAR&HCFFF
20 DEFUSR0=AHD000
30 MEM$(&HD000 f 12)=HEXCHR$(
78 EB 0180 IF 04 ED A3 3D 20 FA C9
第 8 章 DMA 169
J ) リスト 8-19 ( 上 2 ドットグラフィックスクロール)
これも律儀に上下をつなげてある。残念ながら実行してよ一く見ていると色がズレまく
つている。ここらへんが DMA でグラフィックを扱う限界なのかもしれないが,「正しい手
抜き法」を使えばある程度の改善はできるはずである。挑戦してみていただきたい。
スト 8-19
2 ドットグラフィックスクロール
DMAS
1TO200
260
DEFINT A-Z
CLEAR&HDFFF
DEFUSR0=&HE0O0
MEM$(&HEO00 f 12)=HEXCHR$( tf 78 EB 0180 IF 04 ED A3 3D 20 FA C9
INIT : KLIST0 : CLS4 : CIRCLE(320 f 100) 9 60 9 6
PAINT(320 f 100) ,&H62
SYMBOL(282, 100) ••• 朝です ", 2 • 2 • 7 • 0 • PRESET
RESET$ = HEXCHR$ ( ft C3 C3 C3 C3 C3 C3 tf )
> 湾 ft 面
DMA$ = RESET$ + HEXCHR$ ( 11 7D 00 40 CF 07
DMA$ = DMAS ♦HEXCHR$( ff 7D 00 48 CF 37
DMA$ = DMAS ♦HBXCHR$( ff 79 00 78 7F 07
DMA$=DMA$ ♦HEXCHR$( M 79 80 7F 4F 00
•赤 ®
DMA$=DMA$+RESET$
0MA$ = DMA$ ♦HEXCHR$( ff 7D 00 80 CF 07
)MA$=DMA$ +HEXCHR$( M 7D 00 88 CF 37
280 DMA$ = DMA$ ♦HEXCHRS ( ft 79 00 B8 7F 07
)MA$=DMAS ♦HEXCHR$( M 79 80 BF 4F 00
300 ,緣由面
: DMA$=DMA$+RESET$
DMA$=DMA$ +HEXCHR$< M 7D 00 C0 CF 07
DMA$ = DMA$ ♦HEXCHR$( ff 7D 00 C8 CF 37
DMA$ = DMA$ ♦HEXCHR$( ff 79 00 F8 7F 07
350 DMA$ = DMA$ +HEXCHRS ( ff 79 80 FF 4F 00
360 FORK=1TO200 : D$=USR0(DMAS) : NEXT
END
リセツ
データ
1C 10 CD 00 El9A CF 87
1C 18 CD 00 40 9A CF 87
1C 10 CD 50 El9A CF 87
1C 10 CD 00 El9A CF 87
1C 10 CD 00 El9A CF 87
1C 18 CD 00 80 9A CF 87
1C 10 CD 50 El9A CF 87
1C 10 CD 00 El9A CF 87
1C 10 CD 00 El9A CF 87
1C 18 CD 00 C0 9A CF 87
1C 10 CD 50 El9A CF 87
1C 10 CD 00 El9A CF 87
TO ME
IN VRAM
FM ME
FM ME
]EM
IN VRAM
FM MEM
FM MEM
TO
IN
FM
FM
EM
RAM
EM
EM
I ) リスト 8-18 (上 1 ドットグラフィックスクロール)
律儀に上下をつなげてみた0 200回スクロールすると元に戻るわけである。メインメモリ
の E 100„ 番地から E 8 CF „ までの 07 CF h +1バイトをワークエリア(バッファ)にしている
ことに注意0このサンブルプログラムのように上下をつなげる場合にはどうしても必要で
ある0本当のところは,1ラインのスクロールならワークエリアは80バイトで済むのだ
が,そうすると手間がかかり,速度に W いてしまう。
79„はポート B — ポート A への 転送を指定している。
リスト 8-18 上 1 ドットグラフィックスクロール
; COPY
NC
EC
RESET$=HEXCHR$( M C3 C3 C3 C3 C3 C3 M )
f 黹 《 面
DMA$=RESET$+HEXCHR$( M 7D 00 40 CF 07
DMA$=DMA$ +HEXCHR$( M 7D 00 48 CF 07
DMA$ = DMA$ ♦HEXCHR$( ff 7D 00 50 FF 2F
DMA$=DMA$ ♦HEXCHR$( M 79 00 70 7F 07
DMA$ = DMA$ ♦HEXCHR$( ff 79 00 78 7F 07
DMA$ = DMA$ ♦HEXCHR$( ft 79 80 77 4F 00
DMA$ = DMA$ ♦HEXCHRS( ft 79 80 7F 4F 00
’赤曲(面
DMA$ = DMA$>RF.SET$
DMA$=DMA$ +HEXCHR$("7D 00 80 CF 07
DMA$:DMA$ ♦HEXCHRS( ff 7D 00 88 CF 07
DMA$=DMA$ +HEXCHR$(”7D 00 90 FF 2F
DMA$ = DMA$ ♦HEXCHR$( f# 79 00 B0 7F 07
DMA$:DMA$ 4HEXCHR$( ## 79 00 B8 7F 07
DMA$=DMA$ +HEXCHR$<”79 80 B7 4F 00
DMA$ = DMA$ ♦HEXCHR$( ff 79 80 BF 4F 00
’綠 M 面
DMA$=DMA$+RESET$
DMA$=DMA$ +HEXCHR$("7D 00 C0 CF 07
DMA$ = DMA$ ♦HEXCHRS( #f 7D 00 C8 CF 07
DMA$=DMA$ +HEXCHR$(”7D 00 D0 FF 2F
DMAS=DMA$ +HEXCHR$<"79 00 F0 7F 07
DMASsDMAS ♦HEXCHRS ( ff 79 00 F8 7F 07
DMA$ = DMA$ ♦HEXCHH$( ft 79 80 F7 4F 00
DMA$ = DMA$ ♦HEXCHR$( tf 79 80 FF 4F 00
FORK=1TO100 : D$=USR0(DMAS) : NEXT
END
INIT:KLIST0:CLS4:CIRCLE(320, 100),60,2
PAlNT(320 f 100) 9 2 9 2
SYMBOL(240,100> ,••赤九急上舁 •• • 2 , 2 , 7 , 0 , PSET
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
夕
9A CF 87")
CF 87 M )
CF 87”>
CF 87 M )
CF 87">
CF 87">
CF 87”>
9A CF 87">
CF 87”>
CF 87 ff )
CF 87 •い
CF 87..)
CF 87">
CF 87”>
9A CF 87°)
CF 87 M )
CF 87">
CF 87">
CF 87">
CF 87">
CF 87 11 )
TO MEM
TO MEM
IN VRAM
FM MEM
PM MEM
FM MEM
FM MEM
TO MEM
TO MEM
IN VRAM
FM MEM
FM MEM
FM MEM
FM MEM
TO MEM
TO MEM
IN VRAM
FM MEM
FM MEM
FM MEM
FM MEM
以上が転送であった。 DMA の動作には,転送以外にサーチ,サーチ+転送がある。こち
らの使い方も基本的には同じなのだが,多少趣が異なるので,まずはごくごく基本のサン
プルを示す0
K ) リスト 8-20
図 8-10 は実行結果である。まず1000行からのサブルーチンを説明する。
リードレジスタについては一応説明してあったが,これは DMA が実行を終了した後
で,「どれどれお前さんは何をしたのかね」と言いつつノゾキ見るために付いているのであ
る。特にサーチは実行結果が DMA の内部にしか残らないから,どうしてもここを見る必
要がある。そのリードレジスタを DMA から読み出すには何とおりかの方法があるが,另 IJ
に深く悩まず全部読み出してしまえばよいのであった。まずリスト8 -20 の1080行目から
リードレジスタを読み出し,配列 DMA (〜)に代入している。
最初に & HBB を OUT しているが,これは WR 6 のコマンドで「リード•マスク•フォ
ローズ」(後ろに続くマスクを読め)である。その直後の & H 7 がそのマスクである。この
マスクの中の対応するビットが立っていれば ( 1ならば),それに対応する1バイトのリー
ドレジスタを読み出すことになる。1110行の FOR 〜 NEXT 文がそうである。図 8- 8を見れ
図 8-10 サーチの基本技(リスト 8-20) 実行例
11101100
0022
4022
(—4028
11101100
0022
4028
— 4022
これらの数値には意味がない
170 試験に出る XI
0 8 0 0 8 0 8
E E 4 E E E E
0 0 0 0 0 0 0
0 0 0 5 5 0 0
D D D D D D D
c c c c c c C
0 8 0
1 11
C
1
0 8 0 0 8 0 8
E E 8 E E E E
0 0 0 0 0 0 0
0 0 0 5 5 0 0
D D D D D D D
c c c c c c C
0 8 0
1 11
C
11
〇 8 〇 〇 〇〇 〇 8
E E c E E E E
0 0 0 0 0 0 0
0 0 0 5 5 0 0
D D D D D D D
c c c c c c C
0 8 0
1 114
C
1
リスト 8-20 サーチの基本技
100 INIT : CLS4
110 CLEAR &HDFFF
120 OUT&H4020 f «tHFF : 1 V - ^
130 RESET$ = HEXCHR$<”C3 C3 C3 C3 C3 C3 ff ) : f リセット データ
140 1
150 • ボート A を使って、マスクなしで &811111111:& 叩ドをサ-チ
160 DMA$ = RESET$ + HEXCHR$< "7E 00 40 30 00 1C 9C 00 FF Cl 9A CF 8B 87 ff )
170 GOSUB”DISPDMA”
180 1
190 ,ボ - 卜 B を使って、マスクなしで &811111111:& 叩ドをサ-チ
200 DMA$=RESET$+HEXCHR$(”62 30 00 18 9C 00 FF CD 00 40 9A CF 8B 87">
210 GOSUB”DISPDMA”
220 END
230 1
000 LABEL"DISPDMA”
010 GOSUB..SETDMA” : GOSUB”READDMA” : GOSUB”DMPDMA"
020 RETURN
030 *
040 LABEL M SETDMA ff
050 FORI = 1T0LEN( DMAS) : OUT&H 1F80 f ASC (MI D$ ( DMAS f I 9 1)) : NEXT
060 RETURN
070 1
080 LABEL f# READDMA M
090 OUTAHlF80 f AHBB
100 OUT&HlF80 f &H7F
110 FORI=1T07:DMA<1)=INP(&H1F80) : NEXT
120 RETURN
130 1
140 LABEL tf DMPDMA if
150 PRINT RIGHT$( t# 0000000 ff ♦BINS (DMA (1)) 9 8) 9
160 FOR I = 2T06STEP2 : GOSUB..DMPDMA-SUB ••: NEXT
170 PRINT
180 RETURN
190 1
200 LABEL ff DMPDMA-SUB ff
210 PRINTRIGHT$( ff 000 ff 4HEX$(DMA( I >+DMA( I ♦1 > 拿 256 > t 4) f
220 RETURN
ば分かるように,最初の l バイト目はステータスバイトと呼ばれ,各ビットごとに意味を
持つ0その後の2〜7バイト目はそれぞれバイトカウンタ,ポート A アドレス,ポート B
アドレスの上下バイトになっている。ただしこれらの値は DMA の構造上から多少大きめ
の値を示すようになっているので注意が必要である。図 8-10 を見ていただきたい。たしか
に,ポート A のアドレスが & H 4022 となっている。
それでは160行の HEXCHR $ の中のコマンドについて解説する。まず,サーチを実行す
るためには開始アドレスを決め,ポート A , B のどちらかに割り当てなければいけな
い。 A , B どちらでもよいのだが,その場合は WR 0 でソース側(転送元)に指定しておく
必要がある。リスト 8-20 ではポート A (160 行)ポート B (200 行)の両方を使った場合
を示してある。ポートを取り替えたこと以外は同じことをさせている。さて,中程に 9 C H と
いうのがあるが,これが WR 3 である0その直後の00と FF が WR 3 のサブレジスタへの
値である。図 8-5 を参照。マスクバイト (00) というのは「ビットが0なら比較しろ」と
いう意味を持っ。マッチバイトはサーチすべき1バイトのデータである。マスクバイトと
いうのが出てくると,とたんにこんがらがってしまうのだが,
(マッチバイト) OR (マスクバイト) =( ポート A ) の指す データ) OR (マスクバイト)
となれば一致成立ということであると覚えておけばよいだろう。 9 C H は D 2 が1であるから
ストップ•オン•マッチを指定している。さて,他のコマンドは 8 B H 以外は簡単に分かるだ
ろう0 8 B H は WR 6 のステータスバイト初期再設定コマンドである。理由は不明なのだ
第8章 DMA 171
が,サーチを行なう場合はロード コマンド ( CF „) の後にこの コマンドを 送ってやる必要が
あるみたいである。手元にある資料にはサーチの実例がほとんどなく,また説明も不充分
なのである。とにかく, 8 B „ を取り除くと動作がおかしくなる。
L ) リスト 8-21
この中では,ポート A を使ってサーチしている。最初の170行の例は I / O 空間(グラフ
ィック RAM ) 中の4021„番地に OUT してある FF „ を,4000„からサーチしている。200行
は同じように F 0„ をサーチしている0このデータはないので,ブロックレングス (2 F „) +
1個のデータをサーチした後に止まる0転送と同じように,ブロックレングスで指定した
値+1が対象になるのである。230行は FC H をサーチしている。これはちょうどサーチ範囲
の最後にあるので,ステータスバイト(図 8-11 の3行目)の D s ( = 0でエンド •オブ•ブ
ロック),〇 4 (= 0でデータが一致)の両方とも0になっている。260行はマスクを使って
サーチしている。
( FF „) OR (0 F „) = FF „
(4020 の内容 = FE „) OR (0 F „) = FF H
であるから,これは4020 „ の FE „ で一致している。 290 行は,マスクバイトが FF „ であるか
ら,いかなるデータとでも 一致す ることになる。なぜなら,
( XX ) OR ( FF „)= FF „
(△△) OR ( FF „)= FF „
だからである。
320行はサーチはサーチなのだが, WR 3 へのコマンド中で「見つけたら停止」を指定し
ていない(98„)ので,指定したバイト数だけ最後まで処理している。ただしステータスバ
イトの D 4 はちゃんと0 (発見した)になっている0
次にとても面倒なのだが,読み出したレジスタの値は動作モード,条件などによってか
なり複雑に変化する。正しくは参考文献4を見ていただきたいが普通に使う分には「バー
ストモードのサーチで,データが一致したなら,ソースポートのアドレスは発見アドレス
の+2」と覚えておけばよいだろう。その他の場合は実に変幻自在で,このような状況を
押し付けられると,どうも使う気が起きなくなってしまうものである。ただでさえ転送と
違って,利用法の少ない動作なのだからなおさらなのである。さらには,もし WR 3 に「一
致不成立時に停止」という動作が指定できたなら,「0以外のデータを見つける」というこ
ともできたはずなのである。実になまぬるい。
図 8-11 サーチ六態(リスト 8-21) 実行例
11101100
0023
4023
4028
00011000
0030
4030
4028
00001000
0030
4030
4028
00101000
0022
4022
4028
11101100
0002
4002
4028
00001000
0030
4030
4028
j
1
これらの数偃には意味がない
/72拭験に出る XI
リスト 8-21 サーチ六態
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
INIT-.CLS4
CLEAR &HDFFF
OUT&H4020 f &HFE
OUT&H4021 f &HFF
OUT4H402F,&HFC
RESET$=HEXCHR$( M C3 C3 C3 C3 C3 C3 "> : , リセツ
,マスクなしで &B11111111=&HFF をサーチ
DMA$ = RESET$-fHEXCHR$ ( M 7E 00 40 2F 00
GOSUB..DISPDMA"
,マスクなしで &B111 10000 をサーチ
DMA*=RESET$+HEXCHR$("7E 00 40 2F 00
GOSUB"DISPDMA”
,マスクなしで &B111 11100 をサーチ
DMA$ = RESET$-fHEXCHR$ ( M 7E 00 40 2F 00
GOSUB"DISPDMA"
,マスクありで &B1111 ???? をサーチ
DMA$=RESET$+HEXCHR$( M 7E 00 40 2F 00
GOSUB..DISPDMA"
’ マスクありで &B ???????? をサーチ
DMA$=RESET$+HEXCHR$("7E 00 40 2F 00
GOSUB..DISPDMA"
,マスクなしで &B1 1111111 をサーチただ
DMA$=RESET$+HEXCHR$("7E 00 40 2F 00
GOSUB"DISPDMA"
END
データ
1C 9C 00 FF Cl9A CF 8B 87
1C 9C 00 F0 Cl9A CF 8B 87
1C 9C 00 FC Cl9A CF 8B 87 M )
1C 9C 0F FF Cl9A CF 8B 87">
1C 9C FF FF Cl9A CF 8B 87
/ 、停止しない
1C 98 Wd FF Cl
9A CF 8B 87
このあとには、リスト 8-20 の 1000 行目以後を入力してください
まあ,文句はこれくらいにして,次には結構使えそうなモードのサーチ+転送のサンブ
ルを示すのである。
M ) リスト 8-22
サーチ+転送の使い方は, WRO で「転送/サーチ」を指定することと, WR 3 によりマス
クとマッチバイトを指定する以外は(口ードの後の 8 B „ もあるけれど)転送と基本的に同じ
である。もちろん WR 3 で「見つけたら停止」を指定しなければ,転送したデータの中に一
致するデータがあったということだけが後から分かる。サンブルブログラムの中では「.」
(ピリオド)までの文字列をテキスト VRAM へ転送している。もちろんこのとき,ブロッ
クレングスは充分大きな値にしておかなければ,「•」に達する前に動作が停止してしま
う0このサンブルを作ってみて,またもや不満が出てしまった。すなわち,「一致する一つ
前のデータまで転送」というモードが欲しいのである。
ま,文句ばかり言っても仕方ないか。
リスト 8-22 サーチ+転送
100 INITICLS4
110 CLEAR &HDFFF
120 MESSAGE$ = ”WATASI WA DMA DE TBNSOU SARERU. ••
130 MEM$(&HE000,LEN(MESSAGES))=MESSAGE$ :• ソ-スを用意する
140 LOCATE0, 0 : PRINTSPACES (80>: ,アトリビユ-卜の拉定
150 RESET$ = HKXCHR$ ( M C3 C3 C3 C3 C3 C3 M ) : » リセ*•,ト デ-々
160 ,マスクなしで、 •••" までを、 サーチ ♦転送
170 DMA$=RESETS^HEXCHR$( M 7F 00 E0 00 011418 9C 00 2E CD 00 30 9A CF 8B 87"}
180 LOCATE0,3 : GOSUB m DISPDMA m
190 END
200 1
210 ’ このあとには、リスト 8-20 の 1000 行目以後を入力してください •
第8章 DMA
以上で DMA の説明は終わる(ほんとは第9章のディスクのところでまたやるけど)。
で, DMA の良い点の一つとして挙げることができるのが, BASIC 上から機械語を使わず
に,機械語と同じ速度,もしくはそれ以上の速度で処理ができるということである。さん
ざんけなしたけど,サーチだって BASIC でやったのなら実にトロいことになってしまう
のだ。とりあえず DMA にありがとうである。
174 拭験に出る XI
ディスクを回すのである
■第 S 章
鬥ライスクを回芩の T あ5
この章はフロッピーディスクである。そこでまずは参考書について一言。
フロッピーディスク関係の本の中で,ストロングタイプのお勧め品は,参考文献10にも
挙げてある r 最新 フロッピ•ディスク装置とその応用ノウハウ J である。この本は1984年
の発刊で,残念ながらあんまり 「最新」 ではなくなってしまったのだが,プロテクト以外
のことに関しては,ほとんどすべてが載っているので,是非とも手元に置いておきたい一
冊である。
さて,同書によるとフロッピーディスクなるものがこの世に生を受けたのは,1972年の
ことである。 IBM の大型コンピュータに採用されたのだが,確か私の記憶だと, IPL 起動
時のシステム読み込みに使われていたはずである。このときのものは,8インチの片面単
密で,容量は約 250 K バイトであった。当時としては,そのように簡単に取り外しができ
て,しかもランダムアクセス可能な大容世のデバイスは画期的なものだったらしい。
時は移り,それから4年後の1976年に米国シュガート社から5.25インチディスクが発
表された(なんでキッチリ5インチにしなかったんだっ。無意味な不満とともに,以下では
しばしば5インチと呼ぶ)。これは当初は容量が 80 K バイトしかなかったそうである。
8インチと5インチは,その後着々と世に広がり,また技術の向上に伴って記録密度も
上がってくるのだが,三つ子の 魂 百までと言うように,8インチと5インチはちょっと 違
う道を歩むことになる。すなわち,巨人 IBM の手によって生み出された8インチの方は
「 IBM フォーマット」という, 誰も逆らえない スタンダードが根底に確立したのだが,
片や5インチの方は,ほとんど野放しに近い状態となり,いろいろなフォーマットや方式
が乱立することになった。
その中でも一番の被害者は5インチドライブを持つ CP / M ユーザーである。8インチド
ライブの場合は「片面単密度 IBM フォーマット」と一声念じれば,ディレクトリなどに相
当するソフト的なフォーマットも含めてすべてが解決したのだが,5インチの場合は,単
密度しか読めないやつとか,倍密度しか読めないやつとか,内部のディレクトリのエント
リーの数(登録できるファイルの数)が違ったりとか,トラックの数が違ったりとかで,
も一むちゃくちゃになってしまったのだ。その状況は今も変わらず,メディアの互換性は
ほとんど捨ておかれてしまっている。その状況は 3.5 インチでも同じである。ただ一つ明
るい材料といえば,5インチでは MS - DOS フォー マッ トが実質的な標準になりつつある
ということだが,それとても MS - DOS フォー マッ トへのコンバータが必ず入手できるわ
けではない。困ったもんだ。
なおこの章のサンブルブログラムは,特にことわっていない限り 2 D モードで動くよう
になっているので turboZ のユーザーの方などは注意されたい。
176 試験に出る XI
サイズ
メジャー度
8
i
5.25
/
3.5
3
t
表を見て当然気付くだろう か、, 記録方式では8インチの方に 1 D がない(噂によると, ど
こぞに 1 D の8インチドライブがあるそうだが,多分 2 D のドライブの片面だけを使ってい
るのではないかと推測する)。また, 2 DD や 2 HD に相当するものもない。理由は簡単であ
る。 「 IBM カォ作らなかった」からである。それに対して,5, 3.5,3インチの方は 1 D
と 2 S ,1 DD と 2 D のように,同じ容 M なのに違う形式のものがあったりする。この理由も
明白である。 「 IBM が作らなかった」からである。
まずはディスクの回り方などについて説明する。
ディスクの回転速度は8インチが毎分360回転,5インチでは 2 HD が8インチと同じ
く毎分360回転,それ以外は300回転である。 3.5 インチは300回転と600回転の2種類が
あるが,メディアに記録される信号は同じで互換性はある。3インチは毎分300回転で,
第 9 章 フロッピーディスク 177
フ t 2 ツビ_ディスクドライブ勿種類
今まで「5インチ」,「8インチ」,「2 D 」, 「2 DD 」,「2 HD 」 と勝手に書いてきたが,ここ
らでちゃんと説明しておくことにする。
太古の昔には,さまざまな形式のものがあったそうだが,現在の主流はメディアのサイ
ズが,
8,5.25, 3.5, 3インチ
記録方式が,
IS , 2 S , ID , 2 D , 2 DD , 2 HD
となっている。表9-1, 9-2 が大まかな分類と大体の容 M , 個人的な予測である。
表 9-1 メディアの種類
5.25, 3.5, 3インチ
h ■ ■ - - ----
8ィ
ンチ
片面
両面
片面
両面
1 S
(80 KB )
2 S
(160 KB )
1-
1 S
(250 KB )
2 S
(500 KB )
1 D (160 KB )
1 DD (320 KB )
2 D (320 KB )
2 DD (640 KB )
2 HD (1 MB )
/
2 D
(1 MB )
表 9-2 普及度の(個人的な)予測
厂単密 ® - 倍密度
5 インチと同じ。回る方向は,5インチで確認したところ,ラベル側から見て右回り(時
計回り)であった。8インチはよく見えなかったので不明だが,多分同じであろう。
次にディスクの形状であるが,まずはライトプロテクトの方式について少し触れてお
く。8インチの場合は,ディスケットの一部を専用の器具を使って切り欠くことによっ
て,ライトプロテクトの状態になる。切り欠いた所に銀紙を張ると元どおりに書き込める
ようになる0 5インチの場合は逆で,元々切り欠きがあり(最近のゲームソフトなどでは切
り欠きのない特別のディスケットを使っているものもあるが),その状態が書き込み可能で
ある。そこへ銀紙を張るとライトブロテクトされる。だから同じ銀紙でも,8インチの場
合と5インチの場合は機能が逆である0
3.5 インチの場合は,ブラスチック製のスイッチがあり,それをスライドさせることによ
りライトプロテクトになる。スイッチだから元に戻すのも簡単である。
3インチも 3.5 インチと同様にプラスチックのスイッチをスライドさせる方式である0
ただしスイッチは二つある。この理由は後程述べる。
なお,ライトブロテクトであるが, XI の場合はハード的に書き込みができないようにな
るが,一部の機種では絶対に書き込めないとは限らず,コントロールブログラムの方でラ
イトブロテクトになっているかどうかをチェックしてやって,なっていたら書き込み動作
を中止してやる,という処理が必要なものもある。
次にインデックスホールであるが,8, 5,3インチにはあるが, 3.5 インチにはない。代
わりに, 3.5 インチのディスクには位置決めホールがあり,それがインデックスホールと同
じ役目を果たす。
実は3インチにも位置決めホールに相当する部分があり,別にインデックスホールがな
くてもよかったのではないかという気がするが,しっかりとある。
次に「裏表」についてである〇 3.5,3インチでは不明だが,8, 5インチではラベルを張
る面がサイド1,反対側がサイド0である。 IS ,1 D などの片面しか使わないドライブでは
サイド0だけを使っている(ただし例外もある)。
このサイドに関しては,3インチが変わっていて, 1 D 用のドライブに対しては, (2 D 用
の)ディスクを裏返して使うことができる。これがライトブロテクト用のスイッチが二つ
もある理由である。ただし XI の3インチドライブは 2 D 用だから,そのようなことは関係
なく,ディスクを裏返してセットすることはできない。
次に記録形式についてである。
まずは IS ,2 D などの形式について説明を行なっておく。最初に付いている数字は,
「 1 J が片面
r 2 j が両面
を意味している。
次にはアルファべットが1もしくは2文字付くが,これは,
「Sj = 単密度 (Single density)
「Dj = 倍密度 (Double density)
「DDj = 倍トラック倍密度 (Double track Double density)
178 試験に出る XI
「HDj = 高密度 (High Density)
の意味である。
まず,片面と両面の差であるが,これはそのものずばりであるから理解しやすいはずで
ある。片面ドライブと両面ドライブの差は,要するにリード/ライト用のへ ッ ドが 一つ だけ
か,それとも向かい合って 二っ 付いているかである。ただし両面ドライブの 二つのヘッド
はぴったりと向かい合っているわけではなく,少し前後に(数トラック分)ずれている。
次に rs 」, 「 d 」 などに ついて である。これはまず, rs 」 と「その他」に分けられる。 「 s =
単密度」は別名 「FM 記録方式」であり, rs 」 以外はすべて 「MFM 記録方式」であ
る 0 FM は 「Frequency Modulation 」 (周波数変調方式)の略で,これはラジオの FM と
同じである。つまり FM とはラジオだけのことではないのである。これに対して, MFM は
r Modified Frequency Modulation 」 である 0 Modified は,「修正された」というような
意味である。詳しいことは他の参考害に譲るが, FM 記録方式ではクロックパルスというパ
ルスが一定時間 ( 5 インチ 1 S , 2S などの場合で 8;iS = 0.000008 秒)ごとに書かれ,その間
にデータ用のパルスがあれば「1」,なければ「0」である(データは1ビットだけ)。な
ぜこれが FM なのかといえば,全部「1」を書いた場合はパルスの間隔が 4// s になり,そ
れに対して全部「0」を害いた場合はパルスの間隔は8 パ s である。つまりパルスの来る周
期が 4;/s か 8 バ s かで1,0を区別しているのだ。だからやっぱり周波数変調 = FM であ
る。
MFM はどうなのかというと,この方式は大胆にも,「前のデータが 0 で,なおかつ後ろ
のデータも0ならば,間にクロックパルスを入れる。それ以外の場合にはクロックパルス
は書かない」ということになっている。このように修正してやると,「もっとも間隔の狭い
パルスの間」は FM 方式のときの2倍になる。となれば,ディスクの磁性体とヘッドの性
能の余裕は2倍になる(識別できる二つのパルスの間隔が「性能」である)。そこでほっと
一息ついた磁性体とへッドには気の毒だが,クロックパルスの間隔も入れた書き込み速度
全体を2倍にしてやる。これで磁性体やヘッドの性能は基本的に同じままなのに(本当は
そうは単純にいかないのだが),倍のデータを読み書きできることになる。これが倍密度=
MFM である。早い話が,クロックビットを適当に間引くということなのである。「それじ
ゃ,ディスクの回転と同期を取れなくなるじゃないか」という疑問が出てくるであろう(私
もそう思う)。しかしディスクに書かれているのはデータだけではなく,あちこちに同期を
取るための特殊なパルスも書かれていて,ちゃんと読み書きができるのである。これは後
の「物理フォーマット」の所で説明する。
次に 「 DD 」,「 HD 」 にっいての説明である。 「DD = 倍トラック倍密度」であるが,当然
のことながら,ディスクにはトラックというものがあることは知っているだろう。これは
バーム クー ヘンの 年輪みたいなものである。このトラックに沿ってデータが書かれるのだ
が,倍トラックというのはこのトラックの間隔を半分にして,数を倍にしたものである。
結局,めでたく容 M は2倍になる。
最後が 「 HD 」 だが,これは 8 インチと同じ形式を 5 インチに持ってきたものである。卜
ラック数は 2D と 2DD の中間であるが,パルス間隔が 2//S と,半分になり, 1 トラック当
第 9 章 フロッピーディスク 179
たりのデータが多くなっている。それにより全体の容 fi は 2 DD の約 1.5 倍となる。
以上,あれこれ書いたが,結論として言えるのは,8インチ以外のディスクは 彳昆丨屯に
ちているということである。おそらくこれは,急速に技術が向上しているものすべてに言
えることだろうが,この先ど一なるのか考えてみただけでも恐ろしい限りである。最近で
は2インチとかも出てきたし0
トラ,?ウ,セウ9などなど
まず用語について説明する。
① サイド ( side)
表と裏の面のことである。サイド〇,1がある。
② トラック ( track)
1周分の データを 指す。
2 D は1サイド当たり40トラック, 2 DD は1サイド当たり80トラック, 2 HD は1サイ
ド当たり77トラックである。なお,サイド〇,1をまとめて数えて, 「2 D は80トラッ
ク, 2 DD は160トラック」などと言う場合があるが,これは「誤解してください」と言っ
ているのと同じである。できれば, 「2 D は一つのサイド当たり40トラックで,サイドは二
つある」と表現した方がよい(後述のシリングを使う手もある)〇なお,トラックの番号は
外側から〇番,1番……と数える。
ちなみに,サイド0と1では,実際の位置は各トラックで4本分 (2 DD では8本)ずれて
いる。サイド0の方が外側である。これはヘッドの位置がそもそも4本分 (8 本分)ずれ
ているためである。このずれは,ディスクを使ううえではまったく意識する必要はない0
各ディスクにおけるトラック間距離は一定で,表9 -3 に示すとおりである。このことか
らも, FDD というものが高い精度を必要とするデリケートなものであることが分かるだろ
ラ 0
表 9-3 各メディアにおけるトラック間距離
サイズ
トラック間限 ( mm )
8インチ
0.529
5インチ (2 D )
0.529
(2 DD , 2 HD )
0.2646
3.5 インチ (2 D )
0.375
(2 DD , 2 HD )
0.1875
3インチ
0.254
③ シリンダ (cylinder)
サイド0,1の同じ番号のトラックを併せて1シリンダと呼ぶ。 2 D の場合は1枚のデイ
スクに40シリングあることになる。シリングもトラックと同様に外側から〇番,1番…"
と数える。
180 拭験に出る XI
4 セクタ ( sector )
1トラックを何個かに分解してセクタと呼ぶ。実際にデータを読み書きするのはこの部
分である。5インチの 2 D , 2 DD では普通1トラック(片面)当たり16セクタである。セ
クタはトラックと違い,1番,2番, . と番号が付けられている。なお,セクタの数は
16個とは限らない0 5インチの 2 D のまともな フォーマット では,1セクタの容量を256バ
イト,512バイト,1024バイトの中から選べる。それぞれの場合において,1トラック中
のセクタの数は16,9,5となり,ディスク1枚当たりの容童は32 0 K バイト, 360 K バイ
卜, 400 K バイトとなる。ただし裏技で,1トラックに17セクタを作ったりすることも可
能である。
8インチ 2 D と 2 HD の場合,セクタの容童と,1トラック(片面)当たりのセクタ数
は,256バイト—26セクタ,512バイト—15セクタ,1024バイト—8セクタとなる。
当然ながら「容童は大きい方がよいのだから,1セクタは1024バイトにして,1枚当た
りの容 M を 400 K バイトにすべきだ」と考えるかもしれないが,そうした場合,良いことば
かりとは限らない。第一に読み害きは1セクタごとに行なわなければならないので,バッ
ファは 1 K バイト必要になる。さらには,1セクタを読み0きする時間も長くなる。結局デ
ィスクの容童は2割増しになるという利点以外は,「1セクタ256バイトのフォーマット
で,常に4セクタをまとめて読み書きしている」のと似たようなことになってしまうので
ある。さらには,他機種や, DOS とのデータ互換性なども問題になってくる。
本題に入3前に
本当は ディ スクエ ディ タを載せるべきなのかもしれないが,敢えて載せないことにし
た。読み出して表示するだけであれば BASIC に付属の 、、Device dump " があるが,書き
込みの際には別途に ツール が必要になる。
ては,始《3
まずは XI HuBASIC のソフト的なフォーマットについて書く。
一般的に,フロッピーディスクのフォーマットというと2とおりある。「物理フォーマ
ツト」と「ソフトフォーマット」である。物理フォーマットというのは,ディスケット上
に作られた区画のようなものである。前述したように,1セクタの容量などが物理フォー
マットによって決められる。 BASIC に付属している ''FORMAT & COPY . Uty " が物
理フォーマットをディスケットに書き込むわけである。物理フォーマットは1トラックご
とに設定しなければならない点が,普通のデータ書き込みと異なる。普通,5インチの
2 D , 2 DD では,1トラック分のフォーマットを設定するには, 6.25 K バイトのデータを
必要とする。
ソフトフォー マッ トというのは,「ファイルの格納場所」や riPL 起動するファイル
は,このような形式でデイスケツトに書かれていなければならない|などを定めるもので
第9章フロッピーディスク 181
ぁる。
XI のソフト的な フォー マツトの要点は大体次の3点である0
① ディレクトリの構造
② FAT(File Allocation Table ) の構造
③ IPL 起動ブログラムの指定
①のディレクトリというのは,要するに「このディスクにはこんな名前のファイルが入
つている」ということなどを記録してある部分である。ファイル名以外にも,ファイルの
大きさや,書き込まれた日付などもある。つまり名簿のようなものである。②の FAT
は,現在ディスクのどの部分がどのように使われていて,どの部分が空いているかを示す
部分である。③の IPL のブログラム指定は,ディレクトリの一種だと思えばよい。ではま
ず,ディレクトリの説明から始める。
ディレクトリの構造は表 9-4 (turbo の USER,S MANUAL より一部変更) でぁる。 一
つのディレクトリは 32 = 20„ バイトからなる。中身についての前に,レコード番号とクラ
スタ番号を説明しておく 0レコード番号は 5 インチ 2D と 3 インチ 2D では全部で 16X
2 X40 = 1280 個あるセクタに番号を付けたもので,
レコード番号 =( セクタ番号 一 1)
+ ( トラック番号 X32)
+ ( サイド番号 X16)
である。つまり,
トラック0,サイド0
トラック0,サイド1
トラック1,サイド0
トラック1,サイド1
と順番を付けて各セクタに番号を振ったものである。
クラスタというのは,16セクタをひとまとめにしたもので, FILES 命令のときに出てく
る「〇 △ Clusters free 」 の Cluster である。第0クラスタは第〇〜15レコード,次の第1
クラスタは第16〜31レコード……となる。はっきり言って5インチ 2 D と3インチ 2 D で
は,トラック1本分(片面)である。
そこでディレクトリの中身の説明であるが,第0バイトはファイルのアトリビュート(厲
性)を示している。各ビットごとに意味が割り振られているのだが, 00 H と FF H だけは特別
で, 00 H は KILL されたファイル, FF H はここから先はまだ使用されたことのないディレク
トリの領域であることを示す。つまり第0バイトが FF H であるディレクトリ領域に出合っ
たら,後は見る必要がないということである。
各ビットの意味は表にあるとおりだが, turbo で 階層 化ディレクトリが採用されたこと
により,それまで XI で予備になっていた第7ビットが割り当てられた点に注意。また,第
182 试 験に 出る XI
表 9-4 ディレクトリの内容
内 容
_ — — 一- --
0バイト目
種類を表す。 00は KILL されたファイルまたは未使用領域 。 FF
は使用ディレクトリテーブルの終わり。
bitO が1…… Bin ファイル(機械語で 軎 かれたファイル)
bit 1が1…… Bas ファイル ( BASIC テキストで窨かれたファイル)
bit 2が1…… Asc ファイル ( ASCII セーブされたファイル)
bit 4が1…… FILES で表示しない: 0…表示する
bit 5が1……リードアフターライト ON : 0 … OFF
bit 6 が1…… 害き 込み禁止ファイル: 0… 害き 込み 0 K
bit 7 が1……下位ディレクトリ
bit 3は予備
1バイト目〜13バイト目
ファイル名 (13 文字)
14バイト目〜16バイト目
ユーザー指定 EXTENTION エリァ (3 文字)
17バイト目
パスワードのパック(無指定なら 20 h の値)
18 • 19バイト目
ファイルのバイト数 ( Bas および Obj のみ有効)
20 - 21バィト目
ファイルのメインメモリ先頭アドレス ( Obj のみ有効)
22 • 23バィト目
ファイルのメインメモリ実行アドレス ( Obj のみ有効)
24バイト目〜28パイト目
作成された年,月,噃日•時,分が 害き 込まれている。
例ン84年12月01日土噃日,16時36分
先頭から.年年月曜日日時時分分
84 C 6 01 16 36
29バイト目〜31バイト目
ファイル先頭クラスタ値
29バイト目 HIGH バイト (2 D では 0)
30バィト目 LOW バイト
31バイト目 MIDDLE バイト (2 D では 0)
4ビットは SET 命令で 3", 第5ビットは 、' R ", 第6ビットは'、 P " の指定に対応す
次に弟1バイトからの13バイトであるが,これはファイル名である。ファイル名が13文
字に満たない場合は,残りにスペースを詰めることになっている。ファイル名の中にはコ
ントロールキャラクタ,を入れることも可能であるが,そうすると FILES での表示が狂っ
たり,単純には読み出せなくなったりする。昔,それをブロテクトに使ったソフトもあっ
た。次に3バイトは拡張子と呼ばれるもので,「•」の後に付ける 「 Bas 」 とか 「 Uty 」 で
ある。
第17バイトはパスワードである。パスワードとは , 「SAVE ''ファイル名: PASS "」 で
指定できる。実際には文字列なのだが,計算によって1バイトに圧縮されてしまってい
る。だから,違うパスワードであっても,計算の結果同じ1バイトのデータになってしま
うこともあり得る。パスワ ー ドを指定しなかった場合,この1バイトは20„になっている。
第18〜23バイトまでは特に説明する必要はないだろう。
第24〜28バイトは日付である。サブ CPU から読み出したデータと同じ形式である。
第29バイトからの3バイトは,ファイル本体の先頭が書き込まれているクラスタ番号を
指定している。3バイトの数値で , High (上 ), Low (下 ), Middle (中)と,変則的な順
序になっていることに注意。次の FAT の所で説明するが,ファイルの最小単位は1クラス
第9章フロッピーディスク 183
夕である。つまり,1行しかない BAISC のプログラムをセーブしても1クラスタ =4 K バ
イトを使ってしまう。
次に FAT であるが,これは各クラスタの状態(使われて t ゝるかどうか/つながりの順序
など)を示している所である。 XI のフォーマットでは 2 D では第14レコード, 2 DD では
第14,15レコード, 2 HD では第28, 29レコードにある。
まず。各クラスタの状態は次の三つに分かれる。
a ) 使われていない
b ) 使われていて,自分は最後ではない(別のクラスタに続く)
c ) 使われていて,自分が最後のデータを持っている
第 n 番クラスタの状態は , FA 丁の中の2バイトで表される。実際にどの2バイトか
は,デバイスの容 it によって少々複雑なのだが,128クラスタ以下 ( = 512 K バイト)の容
M のデバイス (2 D など)では単純で,「第 n クラスタの状態は, FAT 内の第 n バイト目一
つ」で分かるようになっている0そこで,ここではその場合に限定して説明する。
まずはその1バイトの値が a ), b ), c ) のそれぞれにおいてどうなっているかという
と,
a ) — 0011
b ) — 01••〜 7 F „ (次に続くデータを持つクラスタ番号)
c ) —80„〜8 F „ (7 F „ を引いた値が,そのクラスタ内で実際に使われているレコード
数)
となっている。つまりチェーン状態を表しているのだ。 2 D などでは第0クラスタと第1ク
ラスタ(レコード〇〜 32) はディレクトリと, FAT 自身に使われているので, FAT の先
頭2バイトは常に,
01", 8 F „,
となっている0すなわち「第0クラスタは1クラスタ全部が使われていて,第1クラスタ
に続く〇第1クラスタは 8 F „ — 7 F „ = 16 レコードが実際に使われていて,このクラスタで
チェーンは終わり」である。
M 後の IPL 起動プログラムの指定である。これは第〇レコードに■き込まれて「ディレ
クトリ」に似ているものであるが,次の3点で普通のディレクトリと違う。
① 先頭のアトリビュートは 「 Bin 」 の指定でなければならない
② ファイル名の拡張子は 「 SysJ でなければならない
③ 先頭クラスタ番号を指定する所には,代わりにレコード番号を害き込んでおく
では最初にディレクトリの書き換えを行なってみる0 INIT 命令ですベてのファイルを
消去したディスクに内容の違う BASIC テキストを二つセーブする。そうすると BASIC
テキストのサイズによって若干異なるだろうが,ディレクトリの中身は大体 図 9-1 のよう
になるはずである0そこで二つのディレクトリの「先頭クラスタ番号」 (1 E „ 番目)と「フ
ァイルの大きさ」(12„,13„番目)を交換して書き込んでやる 0 これで「ファイル名が交換
された」のと同じことになる。
もう少しまともな用途としては,うっかり指定した後,忘れてしまったパスワードを解
J 8 J 試験:こ出る XI
これらを交換すると「ファイル名が交換された」ことになる
除したりもできる。そのほか日付の書き換えやファイル名の変更もできる。
次に FAT もいじってみる。ここまでくるとやはり KILL されたファイルの復活が面白
そうである。
まず,充分な大きさの BASIC テキストを作って欲しい。わざわざ打ち込まなくても
RENUMBER と MERGE を繰り返せば長くすることができる。すなわち,
OPTION SCREEN 2 : INIT 、'MEM : "
RENUM 1000: SAVE ''MEM : BT 1", A
RENUM 2000 : SAVE 、'MEM : BT 2", A
とした後で,各 ASCII ファイルを MERGE するなどしていけばよい。
充分に長い BASIC テキストを, INIT 命令ですベてのファイルを消去したディスクにセ
ーブすると,ディレクトリと FAT は大体図 9-2 のようになる。そこでそのファイルを
KILL すると,おのおのは図 9-3 のようになる。違っているのはディレクトリの第 0 バイト
が 00 H で「消去されたファイル」を示していることと,対応する FAT がすべて 00 H に書き
図 9-2 デイレクトリと FAT の例
U 001000=02 52 45 56 49 56 41 4 C 20 20 20 20 20 20 42 61 REVIVAL Ba
0001010=73 20 49 2 D 00 00 00 00 85 A 5 05 07 21 00 02 00 f s I -脑※找!俯
§ 000 Ei 0:00 00 00 00 00 00 00 00 00 Ba Be 00 Be Ba 00 eg : 觀韻離 1 !!
fl 000 E 20=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 •俯俯⑽繼俯
図 9-3 ファイルを KILL した直後のデイレクトリと FAT の例
0001000=00152 45 56 49 56 41 4 C 20 20 20 20 20 20 42 61•识 EVIVflL Ba
0001010=73 20 49 2 D 00 00 00 00 85 fi 5 05 07 21 00 02 00 f s 卜涵※ n ! 獅
B 000 E 00=018 F f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
B 000 E 10=00 00 00 00 00 00 00 00 00 00 的 00 00 00 00 00 •繼繼俯於俯
口 000 E 20=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00,姿俯俯俯獅俯
この部分が変わっている
第9章フロッピーディスク 185
換えられていることである0復活の第一歩に,まずディレクトリに残っているファイルサ
イズから,何クラスタ(何レコード)だったのかを計算する。例では1クラスタ =4 KB 二
4096バイトより,2クラスタと14レコードだったということが分かる。よって,第2クラ
スタは第3クラスタへ,第3クラスタは第4クラスタへ,第4クラスタはそこで終わり
で,14レコード分のデータを持っているから 7 Fh + 14 = 8 Dh となる0そのように書き換えて
いくと,結局図 9-2 のとおりになるはずである。それをディレクトリと FAT の所に書き込
んでやるとファイルは復活する0
しかし実際のファイルの復活はこのように チヨロイ ものではない0何度も SAVE ,
KILL を繰り返したディスクだと,実際のクラスタのつながりが, 2 — 9—10—12 などの
ように飛び飛びになっている可能性があるのだ。「そのときは FAT の00„のクラスタを順
に拾っていけばいいではないか」と思うかもしれないが,それは完全ではない。なぜな
ら,その FAT の00„が復活したいファイルに対応しているとは限らないからである〇 3日
前に KILL したファイルに対応した00„かもしれないのである。だから現実にファイルを
復活するためには,「あ一でもない,こ一でもない」のパズルを繰り返さなければならない
可能性が高いのである。なお, FAT をいじりそこねると 「Bad RecordJ というエラーが
出る。場合によっては竑走することもあり得る。心するよ一に。
ここで turbo の階層化ディレクトリについて説明しておく。はっきり言って構造は簡単
そのものである。つまり, MKDIR はもともとのディレクトリと同じサイズ=1クラスタの
ファイルを作るだけなのである0 CHDIR が実行されたなら,「そのディレクトリファイル
を,ディレクトリのつもりで使う」だけなのである。すなわち,本質的には第1クラスタ
(レコード番号16〜 32) に固定されていたディレクトリ領域を,任意のクラスタに変更でき
るようにしただけなのだ(本当はもっと複雑だが「本質」はそれだけのこと)。いろいろ試
してみて,ダンプさせれば一目で分かるであろう。
次に IPL 起動の指定を実際にやってみることとする。
BASIC ( CZ -8 FB 01) を起動し,例によって INIT 命令でファイルを全部消去したディ
スクを作る。そして,
POKE & H 012 B , & H 00, & H 10
POKE & H 1053, & H 00, & H 10
を実行する。次に,
SAVEM '、ディスク 番号: MONITOR . Sys ", & H 0000, & H 149 F , & H 0000
でモニタと IOCS 部分をディスクにセーブする0モニタを書き換えて縁起が悪いので,
BASIC を再起動する。次に何らかのツールを使って,ディレクトリの最初の1レコードを
第0レコードへコピーする。後は第0レコードの30バイト目を,クラスタ番号(02„)から
レコード番号(20„)に書き換えれば 0 K o なお, IPL 起動のブログラムは連続したレコー
ドに書かれている必要がある。
ここから先では FDC なる LSI に詰め寄り, 抜く手も見せずに フロッピーディスクの
深遠へと向かうつもりである。
186 試験に出る XI
とりあ九ず FDC につい T
FDC (Floppy Disk Controller ) とは,そのものずばりに,フロッピーディスクをコン
トロールするための LSI である。 FDC の種類は,「単密度専用」と「倍密度/単密度両用」
の二つに分かれるが,「単密度専用」はすでに過去の遗物なので,「倍密度/単密度両用」に
ついてのみ書くことにする。
倍 密度/単密度両用 FDC は,
1) FD 1791 ファミリ
2) // PD 765 ファミリ
3) その他
に分かれる。
FD 1791 はウェスタン•デジタル社が開発した FDC で, Xl/Xl turbo に使われている
MB 8877( 富士通製)は FD 1791 ファミリに厲する。それに対して/ / PD 765 は日本電気の開
発した FDC である。当然のことながら,二つのファミリには互換性などというものは存在
しない(それぞれが書き込んだディスケットはもちろんやりとりはできるが)。
ちなみに, FM シリーズの FDC は XI と同じ MB 8877, MZ シリーズは MB 8876 を使っ
ている。8877と8876の違いは,バスラインが正論理か,負論理かの違いだけである。具体
的には,データの1/0が反転するのである。すなわち, XI でディスクに &HFF = &
B 11111111 というデータを書き込み,そのディスクを MZ のドライブに差し込むと&
H 00 = & H 00000000 が読み出せるというわけである。またディスクの表裏 ( SIDE ) も逆で
ある0試してみると分かるが, XI の第0レコード(シリング0,サイド0,セクタ1 ) は
MZ にとっては第16レコード(シリング0,サイド1,セクタ 1) である。逆に MZ の第
0レコードは XI にとっては第16レコードである。
本題に入る。表 9-5 が MB 8877/8876 のコマンド,表 9-6 〜 9-8 が各フラグの意味,表 9
表 9-5 MB 8876/8877 のコマンド
タイプ
■
動 作 |
76543210
XI での襟準的な値
I
0 0 0 0 h V n r 0
02 h =0 0 0 0 0 010
D
0 0 01 h V r » r 0
1 Eh =0 0 0 11110
0 01 u h V ri ro
3 Ah =0 0111010
3
|
ステップ•イン
ヘッドを1トラック内侧へ移動する
010 u h V ri ro
5 Ah =0 1011010
4
ステップ•アウト
ヘッドを1トラック外*へ移動する
011 u h V ri r 0
7 A «=0 1111010
■
5
リードデータ
ディスクのデータ(データフィールド)を at
1 OOmSECO
8(^=1 0 0 0 0 0 0 0
□
ディスク(データフイールド)へデータを香き込む
I
1 10 0 0 E 00
E 0 h =11 10 0 0 0 0
«り込みを姓させる
inn
第9章フロッピーディスク 187
-9,9-10 がステータスレジスタの意味である。ど 一 だ,これだけではちんぷんかんぶんだ
ろう。そこで順に解説してゆくわけであるが,その前に表 9-11 がある0これが X 1/ X 1
turbo での FDC 関係の I/O アドレスである 0 アミかけ部分は XI turbo 用である。これは
後でまたねっとりとやる。
表 9-6 TYPE I コマンドフラグ機能表
フラグ
h
m
能
トラックレジスタ更新フラグ ( U ) は. へッ ド移動に際し,
ることを指示する。
U =1 : トラックレジスタを更新する。
u = 0 I トラックレジスタを更新しない 0
ラックレジスタを 更新す
ヘッドロードフラグ (h ) は,コマンド実行關始時に
メディアから離すかを指示する( XI では無意味)。
h =1:コマンド実行開始時にへッドロー ドする,
h = 0: コマンド実行開始時にへッドを離す。
ッドをロー ドするか
ツドを
トラック照合フラグ( V )は,ヘッド移動後,
スタの照合を行なうかを指示する。
V = 1:トラックの照合を行なう。
V = 0:トラックの照合は行なわない。
ディスクのトラック番号とトラックレジ
ri f ro
ステップレートフラグ ( n , r 0 ) は,ステップパルス出力の間嗝を指定する。
クロック
n r 0
1 MHz 1
( XI ノーマル)
2 MHz
( turbo の 2 HD )
0 0
6 ms
3 ms
01
12 ms
6 ms
10
20 ms
10 ms
11
30 ms
15 ms
表 9-7 TYPE II ,川コマンドフラグ機能 R
フラグ
機 能
m
マルチレコードフラグ (m ) は連統セクタでリード/ライトするかを決める。
m =1:連統セクタ(セクタ番号が增加する方向)でリード/ライトを行なう。
m = 0 :単ーセクタでリード/ライトを行なう。
S
サイドフラグ ( S ) はサイド番号指定に使う。
S = 1:サイド番号の LSB が1のとき一致したものとみなす。
S = 0: サイド番号の LSB が0のとき一致したものとみなす。
(このフラグは, C フラグが1のときのみ有効)
E
ディレイフラグ (E ) は HLT 信号のサンプリングのタイミングを指定する( XI では無意味)。
E =1: HLD (へッドロード)信号を, H •とした後 15 ms 待ち, HLT 信号をサンプリン
グする。
E = 0 : HLD 信号をと した後, 直ちに HLT 信号をサンプリングする。
C
サイド番号比較フラグ ( C ) はサイド番号と比較(チェック)するかどうかを指示する。
C = 1:サイド番号の比較を行なう。
C = 0:サイド番号の比較を行なわない。
ao
アドレスマークフラグ ( ao ) はデータアドレスマークに何を軎くか指定する。
ao = 〇:データアドレスマークに ( FB) H (Data Mark ) を害く 0
ao =1:データアドレスマークに ( F 8 )h (Deleted Data Mark ) を害く。
188 試験に出る XI
-8 TYPE
グ機能表
ni
ni
■
1〇 =1で READY 入力の立ち上がりで IRQ 発生 (IRQ =•
? READY 入力の立ち下がりで IRQ 発生。
プックスバルス検出時に IRQ 発生。
:•無条件で®ちに IRQ 発生
I turbo に使われている MB 8877 の IRQ 信号は OPEN ( どこにも
( つていない)だから • IRQ は何の機能も果たさない。
夕の各ビットの意味
NOT
READY
NOT
READY
WRITE HEAD SEEK
PROTECT ENGAGED ERROR
RECODE
TYPE
NOT
READY PROTECT
RECORD
NOT
FOUND
CRC
ERROR
CRC
ERROR
NOT
READY
NOT
READY
■■■■
■■■■
NOT WRITE WRITE
READY PROTECT FAULT
(今まで実行し
NOT
WRITE
HEAD
READY
PROTECT
ENGAGED
r
TRACKOO
INDEX
>■ i
BUSY
LOST
DATA
I
DATA
REQUEST
BUSY
!
LOST
DATA
DATA
REQUEST
BUSY
LOST
DATA
11 … f
DATA
REQUEST
BUSY
LOST
DATA
DATA
REQUEST
BUSY
LOST
DATA
DATA
REQUEST
BUSY
同様の意味)
TRACKOO INDEX
タスの意味
READY
bit 7)
HEAD ENGAGED
CRC-ERROR
(bit 3)
TRACKOO
INDEX
(bit 1)
OFFCh 出力内容の意味
’、の部分は turbo 用
Ih^HH
イブ No . (0-3)
ド指定
=サイド0
=サイド1
ター 0 N /0 FF
= OFF
= 0 N
TYPE I 访実留
FDC , MB 8877 を実際に使ってみるのである。まず , TYPE I のコマンドは機械語でな
く, BASIC からでも使えるのでちょうどよい肩慣らしである。ただし, FDC を誤って動か
すとディスクの内容がパーになったりすることがしばしばあるので,書き換わってもよい
ディスク以外はセットしておかないように。
FDC を使う前にしなければならないのが,ドライブのセレクトとモーター ON であ
る。これには 0 FFC „ 番地を使うのである。まずドライブ1 (''1:") に壊れてもよい フォ
190 试験に出る XI
ー マット済みのディスクを入れて, BASIC から直接,
OUT & HFFC ,& H 81
と打ち込んでいただきたい。ドライブ1の LED がつき,ディスクが回り出したはずであ
る。不幸にしてドライブ〇しか持ってない人は, & H 81 の代わりに & H 80 である。ドライ
ブ〇が回り出すであろう。冷たいようだ;^以下同様。
いつまで回していても仕方がないので,止めることにする。
OUT & HFFC ,& H 01 (もしくは & H 00)
と打ち込むと,約1秒後にディスクが止まる。なぜ1秒後かというと,これはディスクが
回り出してから,読み書きできるようになるまでに時間がかかるからなのだ(わっかるか
な 一 )0 つまり,普通のディスクアクセス法として,一番自然な方法は,
① ディスクを回し始める
② ディスクが規定の速度(毎分 300 回転)になるまで待つ
③ 読んだり,害いたりする
④ ディスクを止める
となっている。
問題は,①〜④をやった後で,すぐにまた①〜④に飛んでくるケースが多いことにあ
る。④で一旦ディスクが止まってしまっているから,(すぐさま)次にやってきたとき
に,またディスクがアクセス可能な状態になるまで待たなければならない。これでは時間
の無駄が大きいので,④で「モーター OFF 」 の命令を受けても,すぐにはディスクを止め
ず,1秒間の遅延時間を置くのである。これによって,続けざまのディスクアクセスに時
間の無駄が出ず,なおかつソフトウェアで面倒なことをしないで済むのである。めでた
し,めでたし。
では,もう少し進んでみる。 リスト 9-1 である。
リスト 9-1 TYPE I 実習ブログラム
100 OUT &HFFC.&H81 : , MOTOR ON "1:"
110 GOSUB"WNBSY"
120 OUT &HFF8 , &H2 : ’RESTORE (第 0 トラックヘシ - 々)
130 GOSUB"WNBSY"
140 OUT &HFFB,20 :’データ レジスタ—目的トラック番号
150 OUT &HFF9 ,0 :, トラックレジスタ♦現在のトラック番号
160 OUT &HFF8.&H1E : , SEEK
170 GOSUB"WNBSY"
180 OUT &HFF8.&H5A : , STEP IN
190 GOSUB..WNBSY"
200 OUT &HFFC f &Hl
210 END
220 し ABEL"WNBSY”
230 PRINT"】•• ; SPACE$( 3> ;
240 STAT=INP(&HFF8) : , GET STATUS BYTE
250 PRINT RIGHT$( M 0 M +HEX$(STAT),2) ; SPACE$(2 );
260 IF STAT AND &H81 THEN 240
270 PRINT" : ••: RETURN
まずは FFC H —81 H で,ドライブ 1 のモーターを ON する。 GOSUB 、' WNBSY "で,デ
ィスクが正しく定常状態になるまで待つ。次に FF 8 H 番地(コマンドレジスタ)へ 02 H (表
9-5 のリストアコマンド)を OUT する 0 これで,ドライブ1のヘッドは第0トラック(一
第 9 章 フロッピーディスク 191
まず'']"は, 「 WNBSY が始まったよ」という意味である。最初のやつは,モーター
0 N から定常状態になるまで待っているわけだから,案の定 A 0„ = 10100000 B で第7ビット
が1である。いっしょに第5ビットも立っているが,これは「へッドがディスクに押し付
けられている」ということを示している——はずだが,どっこい,実は XI ではこの信号
は何の意味も持たないのであった。
ちょっと深入りするが , FDC — FDD の間には HLD と HLT という信号がある 。 HLD
は FDC から FDD への「へッドをディスクに押し付けなさい」という信号である。 HLT は
FDD から FDC への信号で「私こと FDD はディスクにへッドを押し付けました。謹んでご
報告いたします」というものである。しかし XI では, HLD はオープン, HLT は 5 V ヘプ
ルアップされているのだ。すなわち, HLD 信号は何にも使われておらず, HLT は常に
192 試験に出る XI
番外側)へ移動してくれる。もちろん,ヘッドという重さのある r ブツ」が動くわけで多
少の時間がかかるから,130行の GOSUB '' WNBSY " で動作の完了を待ってやる。
140〜170行は「シーク」である。このコマンドの使い方は,まず下準備として, FFB H 番
地(データレジスタ)に目的トラック番号を OUT し, FF 9 H 番地(トラックレジスタ)へ
現在のトラック位置を OUT する。次にコマンドレジスタヘシークコマンド (1 E „) を送る
のである。以上のことをすると,ドライブは「ククククッ」という音を立てて,目指す卜
ラックへ動いてくれる。
その次はステップインで,これは要するに1トラックだけ内側にシークする0
さて,220行からのサブルーチンであるが,これは FF 8 H (ステータスレジスタ)を見張
りつつ, MSB と LSB (第7ビットと第0ビット)がともに0になるのを待つものであ
る。第7ビットは 「NOT READY 」, すなわち「まだ準備できてないよ」という意味。第
0ビットは 「 BUSY 」, すなわち「いま忙しいのっ!」もしくは「まだほかのことしてる最
中でんがな。そないにせかさんといてや」という意味である。注意しておくが, I / O の FF 8„
番地は,
OUT したときは コマン ド レジスタ
IN したときは ステータスレジスタ
となっている。1番地2役なのだ。
このブログラムでは,ステータスの内容をチェックする意味で,いちいちブリントさせ
ている。実行結果は,図 9-4 のようになるはずである。ちょっと見てみる。
図 9-4 「リスト 9- lj の実行例
0 0 1 1
A A 0 2
0 0 1 1
A A 0 2 2
0 0 1 1 0
A A 0:22
0 0 14 11
A A 0 0 2 2
0 0 15 11
A A 0 0 2 2
0 0 1111
A A 0 0 2 2
0 0 1111
A A 0 0 2 2
0 0 1111
A A 0 0 2 2
0 0 1111
A A 0 0 2 2
0 0 4J 111
A A 0 0 2 2
0 2 1111
A A 0 0 2 2
o 0 11II 1A
AA ••0022 •
00011110
AA 200222
00011111
AAA 00222
0 0 1 1
)A- A 1J 0 —J 21J
High のままである。これはどういうことかというと,5.25インチ以下のサイズのフロッピ
ー ディスクドライブでは一般的に「ヘッドは常にディスクに押し付けられているから」な
のだ。 XI のディスクでもそうなっている。よって第5ビットは無視すべきである。
さて,図 9-4 の2行目の中程に 「 A 2」 というのが1か所出てくる。これは第1ビットが
立っているのである。表 9-9 から 「 INDEX 」 と分かる。すなわち, FDC はこの瞬間にイン
デックスホールを検出したのだ。後はず一っと A 0„ で,最後に第7ビットが0になり 「NOT
READY ではない」すなわち「用意できたよ一ん」となって " WNBSY ,7 からリターンす
るのである。言い遅れた力へこのようなステータスになるのは,直前(最後)に FDC に
送られたコマンドが TYPEI のコマンドだったからである。しかし, TYPE が何であって
も 「NOT READY 」 と 「 BUSY 」 は同じことだから,悩む必要はない。
次に nVNBSY " に来るのは , RESTORE (リストア:トラック0へのシーク)のとき
である0ステータスは01„ = 00000001 B と, BUSY が並んでいる。最後の方は,05„, 04 H と
なっている。05„は表 9-9 から分かるように 「 TRACK 00 です& BUSYJ である。ちょ
っと待て!てめ 一, すでに TRACK 0に来てるんなら, RESTORE 動作は終わってんじ
ゃね 一 か。それなのに BUSY とは何事だ,と一瞬逆上するが,次の04„で FDC は BUSY
を取り下げている。む一ん。それにしても第5ビットが0だ-体ど一なっているの
だ。ま,無祝しておこう。
次がシーク コマンド 後の 、、 WNBSY " である。おっと, 21 H = 00100001 B だ。 いやいや 無
視無視。え一と,こっちは平凡に BUSY が0になって終わりである。
最後がステップ•インである 0 これはシークと同じであるが,移動距離が短いので,あ
っという間に終わっている。
以上で図 9-4 の実感放送を終わる。
ではまず,シークコマンドについて少々補足しておく。シークコマンドでは,
データレジスタ—目的トラック番号
トラックレジスタ—現在のトラック番号
とセットするわけだが,ど一してこんな面倒なことをするのかというと, FDC が何台もの
FDD を管理しているからなのだ。つまり,何台もの FDD を操作しているのだから,「現在
のトラック番号」は XI の場合最大で四つある0本来なら,トラックレジスタは移動後の「卜
ラック番号」を保持しているので,1台のドライブだけを動かしている場合は,目的トラ
ック番号をデータレジスタにセットするだけで OK なのである。しかし現実はほとんどの
システムで FDD は2台以上あるから , DOS (もしくはディスク BASIC ) は4バイトのワ
ークエリアを 持っていて,いちいちトラック番号を保持,書き込みしてやらなければなら
ない0
トラックレジスタがトラック番号を持っていることを確認するためには,
175 PRINT INP (& HFF 9)
195 PRINT INP (& HFF 9)
を入れてやればよい。「20」,「21」と表示されるはずである。
次に大事な「フラグ」について説明する 0 リストアには, h , V , n , r 0 の四つのフラグ
第 9章フロッピーディスク 193
があり,各動作を指定している。まずは表 9-6 を見ると,
h = へッドロー ドフラグ
とある。これはさっき言ったように無意味である。次に,
V = トラック照合フラグ
である。これは実際にディスクを読んで,チェックするかどうかのフラグである0ディス
クには「私は第△トラックの第 x サイドの第〇セクタです」という 「 ID 」 が書かれている
のだ0これを読んで,ヘッドが本当に目的のトラックに達したかどうかのチェックを指定
するフラグである。リスト 9-1 では 02 H だから V = 0で,チェックは行なっていない。これ
については,後で実験する。
次に r M r 0 であるが,これは二つで一組で, 00 B 〜 11 B までの四つの場合があり,これはス
テッブレートを指定するものである。ステップレートは表 9-6 に示してある「時間」であ
る。なぜこんなものがあるかというと,これは 「 FDD のヘッドを動かす速さ」に機種ごと
に差があるからなのだ(一般に高価な FDD ほど速い)。 FDC は FDD に「へッドを動かし
なさい」という信号を送るのだが,その信号は「方向(内側へか外側へか)」と「動け」だ
けなのだ。 FDD は一般にタコだから, FDC の方でタイミングを取ってやらないといけ
ない。そのタイミングを指定するのが r M r 0 のステップレートなのである 0 たとえばリスト
9-1 のように1^=1, r o =0 を指定すると, FDC は FDD に対して 20 ms (0.02 秒)ごとに
「動け」と指令を出すことになる 0 さて,実は XI ではステップレートは別に 20 ms でなく
てもよいのである。
3インチ= 3 ms
turbo の内蔵= 6 ms
CZ -502 F , 503 F = 6 ms
古いタイプ(レバーのないやつ) =20 ms
などとなっている。
そこで リスト 9-2 が「ガリガリ」ブログラムである。これは指定したステップレート
で,ひたすらトラック 0 — 39 間を動くというものである。しつこくやったり,性能以上の
速度で動かそうとすると故障の原因になるから,ほどほどにやること。性能を超えた場合
は「32」とか「30」(第4ビット=シークエラーが 1) などが表示されるはずである。
後に残っているのは, STEP などの,
u = トラックレジスタ更新フラグ
である。これは「ヘッドの移動にともなって,トラックレジスタの値を増減させるか,さ
せないか」のフラグである。リスト 9-1 で180行の & H 5 A を & H 4 A にして,
195 PRINT INP (& HFF 9)
を追加すると「20」と表示されるはずである。実際には,へッドは第21トラック上にある
のだが,トラックレジスタはそうなっていないのである。
なぜこんなフラグがあるかというと,フロッピーディスクの始祖, IBM フォーマットに
は「欠陥トラック」というものがあるためなのだ。たとえば,ディスクをフォーマットし
ているときにどうしても正常に読み書きできないトラックを発見したとする0現在のパソ
194 試験に出る XI
リスト 9-2 ガリガリプログラム
100 INPUT "STEP RATE** ; S:IF (S<0) OR (S>3) THEN 100
110 OUT &HFFC f &H81 : , MOTOR ON "1:"
120 GOSUB M WNBSY"
130 OUT &HFF8,&H0+S
140 GOSUB"WNBSY"
150 OUT &HFFB,39
160 OUT &HFF9,0
170 OUT &HFF8,&H1C+S
180 GOSUB"WNBSY”
190 IF INKEY$(0)= MM
200 OUT &HFFC,&H1
: RESTORE ( 第 0 トラックへシーク)
»データ レジスタ—目的トラック番号
’ トラックレジスタ♦現在のトラック番号
f SEEK
THEN 130
210 END
220 LABEL m WNBSY
230 PRINT" 】 " ; SPACE$<3>
240 STAT=INP(&HFF8) : , GET STATUS BYTE
250 PRINT RIGHT$<"0"+HEX$(STAT>,2};SPACE$(2>;
260 IF STAT AND &H81 THEN 240
270 PRINT** : M : RETURN
コンではそんな場合には「エラーだよ,このディスクは使えません。ぴぴっ」とメッセ ー
ジを出して,別のディスクを使うように要求するのだが, IBM フォーマットでは,「交替用
トラック」が2トラック分(本当はシリングと表現すべきだが)用意されていて,多少の
欠陥のあるディスケットでも使えてしまうのである。ご丁寧にも,その欠陥のあるトラッ
クを指定する方法も決まっている。この場合に,欠陥のあるトラックを飛ばしてフォーマ
ットすると,実際のヘッドの位置と,ディスクに書かれている rmj に違いが出てしまう
ことになる。そうなると, V フラグでチェックしたときにシークエラーが出てしまうなど
して都合が悪いので, U フラグを使って「つじつまを合わせる」のである。大昔は磁性体
の品質が低かったり,ディスク(メディア)も高かったりしたから,そんなことをしたの
だろうが,今はほとんど意味がないと言えるフラグである。しかし, IBM フォーマットが
いかに「金科玉条」であるかのよい証拠でもある。
というところで,少々遊んでみることにする。まずはフォーマットされていない,まっ
さらのディスクを用意していただきたい。それをドライブ1に入れてもらう。その状態
で,リスト 9-1 を実行すると,3番目のシークコマンドのステータスで,最後に 30 H が出る
はずである。すなわちシークエラーである。これは別にフォーマットされているディスク
でも,ステップ•インで , u = 0, V = 1(つまりコマンドは & H 4 E ) とすると同じことが起
こる。トラックレジスタの値は「20」なのに, V フラグに従ってチェックしてみると,第
「21」トラックだった,というわけである。
TYPE I コマンドで言い残したのは, STEP コマンドだけである。このコマンドを実行
すると,ヘッドは内/外どっちに動くのかということであるが,「直前に動いた方」に動く
ということである。すなわち, FDC は「最後に動いた方向」を保持しているというわけで
ある。
第 9 章フロッピーディスク 195
TYPE n め実習
TYPE I では 機械語を使う必要がなかったが , TYPE II では さすがに そうはい かな
い。そこで, リスト 9-3, 9-4, 9-5 である。 例によって リスト 9-3 は 機械語 プログラムの
アセンブルリスト,リスト 9-4 はダンプリスト,リスト 9-5 はそれを BASIC から使うた め
のプログラムである。
BASIC は CZ -8 FB 01 の Ver 1.0
でなければならない。なぜかというと,場合によっては EOOO „ 〜 F 800 H ぐらいまでをワー
クエリアに使ってしまうので , turbo BASIC では動かない(暴走するかもしれない)から
である。
スト9-
3ディスクアクセスブログラム
• Z80
參
.PHASE 0DF00H
0FF8
CR
EQU
0FF8H
;COMMAND REG.
0FF8
STR
EQU
0FF8H
; STAT. REG.
0FF9
TR
EQU
0FF9H
;TRACK REG.
0FFA
SCR
EQU
0FFAH
;SECTOR REG.
0FFB
DR
EQU
0FFBH
;DATA REG.
0FFC
MSDR
EQU
0FFCH
••MOTOR, SIDE, DRIVE 参 SELECT
DF00
D5
START
: PUSH
DE
••SAVE DE FOR RETURN STATUS
DF01
1A
LD
A f (DE)
•GET COMMAND No.
DF02
13
INC
DE
DF03
D5
PUSH
DE
DF04
21 DF1A
LD
HL f JTA
; HL=JUMP TABLE AREA
DF07
16 00
LD
D f 0
DF09
87
ADD
A 9 A
DF0A
5F
LD
E,A
;DE=A 拿 2
DF0B
19
ADD
HL,DE
DF0C
5E
LD
E, (HL>
DF0D
23
INC
HL
DF0E
56
LD
D 9 (HL)
••GET JUMP ADDRESS
DF0F
EB
EX
DE f HL
; HL=JUMP ADDRESS
DF10
D1
POP
DE
DF11
F3
DI
DF12
CD DF19
•
CALL
PATCH
;CALL (HL)
DF15
FB
t
El
DF16
D1
POP
DE
••GET STRING ADDRESS
DF17
12
LD
(DE),A
;STORE LAST STATUS
DF18
C9
•
RET
;RETURN TO BASIC
DF19
E9
PATCH :
JP
(HL)
: CALL (HL)
t
•
t
參
Jump
Table Area
••TYPE
i
DF1A
DF32
JTA :
DW
RSTR
;RESTORE
DF1C
DF3C
DW
SEEK
••SEEK
DF1E
DF55
DW
STEP
••STEP
DF20
DF55
DW
STPIN
••STEP IN
DF22
DF55
•
DW
STPOT
••STEP OUT
•: TYPE
II
DF24
DF5F
DW
READD
••READ DATA
DF26
DF84
•
DW
WRITD
;WRITE DATA
;TYPE
III
DF28
DF5F
DW
READI
;READ ID
DF2A
DF5F
DW
REDTR
••READ TRACK
DF2C
DF84
•
DW
WRITR
-.WRITE TRACK
;TYPE
IV
DF2E
DFBC
DW
FORI
;FORCE INTERRUPT
••MOTOR,SIDE,DRIVE#
196 試験に出る XI
0FF8
79
DFD2
0FF9
59
0FFB
51
0FF8
79
DFD2
DFC6
1A
01 0FF8
ED 79
CD DFD2
C9
CD DFEA
01 0FF8
D9
01 0FFB
2A DFFE
D9
ED 79
CD DFE4
ED 78
0F
30 0B
0F
30 F8
D9
ED 78
77
23
D9
18 F0
CD DFEA
01 0FF8
D9
01 0FFB
2A DFFE
D9
IE 00
16 02
ED 79
ED 78
A2
C2 DFA4
ID
C2 DF98
18 06
D9
7E
ED 79
23
D9
ED 78
0F
30 0B
DF30
DF32
DF33
DF36
DF38
DF3B
DF3C
DF3D
DF3E
DF3F
DF40
DF4 1
DF42
DF45
DF47
DF4A
DF4C
DF4F
DF51
DF54
DF55
DF55
DF55
DF56
DF59
DF5B
DF5E
DF5F
DF5F
DF5F
DF62
DF65
DF66
DF69
DF6C
DF6D
DF6F
DF72
DF74
DF75
DF77
DF78
DF7A
DF7B
DF7D
DF7E
DF7F
DF80
DF82
DF83
DF84
DF84
DF87
DF8A
DF8B
DF8E
DF91
DF92
DF94
DF96
DF98
DF9A
DF9B
DF9E
DF9F
DFA2
DFA4
DFA5
DFA6
DFA8
DFA9
DFAA
DFAC
DFAD
#
DW
MSD
••MOTER,SIDE,DRIVE#
RSTR :
LD
LD
A,(DE)
••COMMAND
BC,CR
; BC=COMMAND REG.
OUT
(C) f A
CALL
WNBSY
••WAIT READY
•
RET
SEEK :
EX
LD
DE.HL
A f (HL)
; A=COMMAND
INC
HL
LD
D f (HL)
; D=TRACK# TO SEEK
INC
HL
LD
LD
E f (HL)
BC f TR
; E=CURRENT TRACK#
OUT
(C) f E
••SET CURRENT TRACK#
LD
BC f DR
OUT
(C) f D
••SET TRACK TO SEEK
LD
BC f CR
OUT
(C) f A
••SEND SEEK COMMAND
CALL
WNBSY
;WAIT f NOT BUSY*
•
RET
STEP :
STPIN :
STPOT :
LD
LD
A,(DE)
BC f CR
;GET COMMAND
OUT
(C) t A
CALL
WNBSY
•
RET
READD :
READI :
REDTR :
CALL
SETSCT
; A=COMMAND,SET SECTOR REG
LD
BC t CR
; CR=STR
EXX
LD
LD
BC f DR
; BC f =DATA REG.
HL f (BUFAD) ; HL f =BUFF ADD.
EXX
OUT
(C) , A
: SET COMMAND
CALL
WAIT1
REDl:
IN
A, (C)
;GET STATUS
RRCA
;CHECK BUSY
JR
NC.RED2
;END READ
RRCA
;CHECK DATA REQUEST
•
JR
NC.RED1
;NO REQUEST
t
EXX
IN
LD
A, (C)
;GET DATA
(HL) ,A
;STORE DATA
INC
HL
: INC BUFF. ADDR.
EXX
•
JR
REDl
••AGAIN
RED2 :
RLCA
;BACK STAT (RRCA <-> RLCA)
•
RET
WRITD :
WRITR :
CALL
SETSCT
; A=COMMAND,SET SECTOR REG
LD
BC.CR
; CR=STR
EXX
LD
LD
BC.DR
;BC»=DATA REG.
HL,(BUFAD) ; HL f =BUFF ADD.
EXX
LD
LD
E.00H
••COUNTER
D f 02H
••MASK
OUT
(C) f A
;SET COMMAND
FLOOP :
IN
A f (C)
;FIRST LOOP
AND
D
JP
NZ,FIRST
;FIRST DATA REQ.
DEC
E
;DBC COUNTER
JP
JR
NZ,FLOOP
WRTl
;AGAIN
••QUIT FIRST LOOP
FIRST :
EXX
LD
A, (HL)
;GET FIRST DATA
OUT
(C) f A
;WRITE 1 BYTE
INC
HL
;INC BUFF. ADDR.
EXX
WRT1:
IN
A, (C)
••GET STATUS
RRCA
;CHECK BUSY
JR
NC f WRT2
: END WRITE
A 1 n D 9 BE363E1D1H1DD9
1 0 E c c E 725250 E0EOECC
第 9 章フロッピーディスク 197
DFKA
DFEB
DFEC
DFKD
DFEE
DFK1
DFF3
DFF4
DFF7
DFF8
DFD2
DFD3
DFD5
DFD7
DFDA
DFDC
DFDD
DFDF
DFE1
DFE2
DFE3
DFB2
DFB3
DFB4
DFB6
DFB7
DFB8
DKFK KOO0
DFF9 00 00 00 00
DFFD 00
DFE4 3E 07
DFE6 3D
DFE7 20 FD
DFE9 C9
DFC6 1A
DFC7 01 0FFC
DFCA ED 79
DFCC B7
DFCD F0
DFCE CD DFD2
DFD1 C9
DFBC 1A
DFBD 010FF8
DFC0 ED 79
DFC2 CD DFD2
DFC5 C9
DFBA
DFBB
07
C9
DFAF 0F
DFB0 30 F8
RRCA
;CHECK DATA REQUEST
•
JR
NC.WRTl
;NO REQUEST
•
EXX
LD
A, (HL)
;GET DATA
OUT
(C) ,A
;WRITE DATA
INC
HL
;INC BUFF. ADDR.
EXX
•
JR
WRT1
;AGAIN
WRT2 :
RLCA
;BACK STAT (RRCA <-> RLCA)
傭
RET
FORI :
LD
LD
A,(DE)
BC t CR
;GET COMMAND
OUT
(C) f A
CALL
WNBSY
•
RET
—
M3D :
LD
LD
A,(DE)
;GET DATA
%
BC,MSDR
OUT
(O f A
••SET IT
OR
A
;MOTOR ON?
RET
P
;MOTOR OFF THEN RET
CALL
WNBSY
••WAIT READY
•
RET
WNBSY :
PUSH
BC
: SAVE BC
LD
B f 20H
WNBSY0 :
DJNZ
WNBSY0
••WAIT
WNBSY1 :
LD
BC t STR
;DASAI
IN
A f (C)
LD
C f A
;SAVE STATUS
AND
81H
;CHECK
JR
LD
NZ,WNBSY1
A f C
;GET STATUS
POP
BC
••GET BC
•
RET
WAIT1 :
LD
A,7
••WAIT ROUTINE
WAIT2 :
DEC
A
JR
NZ f WAIT2
•
RET
SHTSCT :
EX
DE.H し
LD
A f (HL)
; A=COMMAND
INC
LD
LD
H し
D f (HL)
; D=SECTOK#
BC f SCR
; BC=SECTOH REG.
OUT
(C) f D
;SET SECTOR#
PUSH
AF
••SAVE COMMAND
CALL
WNBSY
POP
AF
;GET COMMAND
•
RET
1
DB
0,0|0.0t
0 ;DUMMY
BUFAD :
•
DW
0E000H
;BUFFER ADDRESS
•
END
まずリスト 9-5 の使い方からである。基本的なパターンは,
番号 (0 〜 11), コマンド,パラメータ…
を CHRS で文字列に変換した後に USR 0 (〜)である。詳しくは表 9-12 に示す。11番だけ
は FDC への コマンドではなく, FFC „ 番地へのデータであることに注意0
なお,このプログラムは手抜きのお手本みたいなもので,ちゃんとしたエラー処理をし
ていない。たとえばディスクを抜いて,ドライブのモーターを ON にしようとすると,帰
ってこないのである。そのときは心静かにリセットスイッチを押していただきたい。
では,おもむろにリスト 9-3 の解説を始める0
A 2
F D
F 1 F
0 5 D
BE361D5D19
E7250EFCFC
0 E F 8 16
2 F 0 7 8 F
5601DF 60919
C010E4E27CC
9 0
7 F
9 E D 3 9 8
D 7 E 2 D 1
198 試験に出る XI
DF80
DF88
DF90
DF98
DFA0
DFA8
DFB0
DFB8
DFC0
DFC8
DFD0
DFD8
DFE0
DFE8
DFF0
DFF8
リスト 9-4 「リスト 9-3 j のダンプリスト(念のため:チェックには付録 A を参照のこと)
DF00 D5
DF08 00
DF10 D1
DF18 C9
DF20 55
DF28 5F
DF30 C6
DF38 CD
DF40 23
DF48 FB
DF50 79
DF58 0F
DF60 EA
DF68 0F
DF70 E4
DF78 30
SUM : 69 F31C A0 7A AD 85 E2 43E7 SUM : 6A 7F EE 56 A4 E0 A9 89 EC8E
100
CLEAR &HDF00
110
MEM$(4HDF00 f 16)=HEXCHR$( 1
D5
1A 13 D5
21
1A
DF
16
00
87
5F
19
5E
23
56
EB" >
120
MEM$(&HDF10 f 16)=HEXCHR$( f
D1
F3 CD 19
DF
FB
D1
12
C9
E9
32
DF
3C
DF
55
DF ff )
130
MEM$(&HDF20 9 16 )=HEXCHR$( 1
55
DF 55 DF
5F
DF
84
DF
5F
DF
5F
DF
84
DF
BC
DF" >
140
MEM$(&HDF30 f 16)=HEXCHR$C
C6
DF 1A 01
F8
0F
ED
79
CD
D2
DF
C9
EB
7E
23
56" >
150
MEM$(&HDF40 f 16)=HEXCHR$( f
23
5E 01 F9
0F
ED
59
01
FB
0F
ED
51
01
F8
0F
BD ff )
160
MEM$(&HDF50 f 16)=HEXCHR$( f
79
CD D2 DF
C9
1A
01
F8
0F
ED
79
CD
D2
DF
C9
CD 11 )
170
MEM$(&HDF60 t 16)=HEXCHR$(•
EA
DF 01 F8
0F
D9
01
FB
0F
2A
FE
DF
D9
ED
79
CD ff )
180
MEM$(&HDF70,16)=HEXCHR$( f
E4
DF ED 78
0F
30
0B
0F
30
F8
D9
ED
78
77
23
D9">
190
MEM$(&HDF80 f 16)=HEXCHR$( f
18
F0 07 C9
CD
EA
DF
01
F8
0F
D9
01
FB
0F
2A
FE ff )
200
MEM$(&HDF90 f 16)=HEXCHR$( f
DF
D9IB 00
16
02
ED
79
ED
78
A2
C2
A4
DF
ID
C2 M )
210
MEM$(&HDFA0 9 16)=HKXCHR$( 1
98
DF 18 06
D9
7E
ED
79
23
D9
ED
78
0F
30
0B
0F tf )
220
MEM$(4HDFB0 9 16)=HEXCHR$( f
30
F8 D9 7E
ED
79
23
D9
18
F0
07
C9
1A
01
F8
0F ff )
230
MEM$(&HDFC0 f 16)=HEXCHR$(•
ED
79 CD D2
DF
C9
1A
01
FC
0F
ED
79
B7
F0
CD
D2 ft )
240
MEM$(&HDFD0 t 16)=HEXCHR$(•
DF
C9 C5 06
20
10
FE
01
F8
0F
ED
78
4F
E6
81
20 tf )
250
MBM$(&HDFE0,16)=HBXCHR$( f
F6
79 Cl C9
3E
07
3D
20
FD
C9
EB
7E
23
56
01
FA ff )
260
MEM$(&HDFF0 f 16)=HEXCHR$ <•
0F
ED 51 F5
CD
D2
DF
FI
C9
00
00
00
00
00
00
E0 M )
270
DEFUSR0=&HDF00
280
D$=USR0(CHR$(11 9 &H81))
: 1 MOTOR
ON
290
D$=USR0(CHH$(0 f &H2))
: 'RESTORE
300
D$=USR0(CHR$(1 f &HlE 9 2 9 0))
: f SEEK
310
1 D$=USR0(CHR$(2 f AH3A))
: f STEP
320
1 D$=USR0(CHR$(3 f 4H5A))
: 1 STEP IN
330
1 D$ = USR0(CHR$(4 t AH7A))
: f STEP OUT
340
D$=USR0(CHR$(5 f AH80 f 1))
: 1 READ DATA
350
f D$=USR0(CHR|(6 f &HA0 f 1))
: 1 WRITE
DATA
360
f D$=USR0(CHR$(7 f &HC0 f 1))
: f READ ADD*
370
f D$=USR0(CHR$(8 f AHE0 f 1))
: 1 READ TRACK
380
f D$=USR0(CHR$(9 f &HF0 f 1))
: 1 WRITE
TRACK
390
f D$=USR0(CHR$(10 f &HD0))
: , FORCE
I NT
•
400
D$ = USR0(CHR$(ll f «tHl))
: f MOTOR
OFF
410
END
DFOO „ 〜 DF 19„ は,〇〜 11 番のうちの,どこへ飛び込むかを計算している。最初に DE レ
ジスタを PUSH しているのは,後々ステータスを返すためで ある。 DF 11„ に 「 DI 」 があっ
て割り込みを禁止しているが,これはディスクリード/ライトのようにタイミングが大事な
プログラムでは必要なことで ある。 DF 12„ では DF 19„ の 「JP ( HL )」 とともに , 「CALL
( HL )」 に相当することをやらせている。実際のルーチンは後回しにして, DF 15 h 〜 DF 18 h
を説明する。ディスクにアクセスして帰ってきたときに, A レジスタは最後に読み出した
ステータスレジスタの値を持っているようにして ある。 その値を DE レジスタの指すアド
レスにストアすると,このプログラムで呼び出した BASIC で,
F34B2A1A8722B
615 2 5 B E
F c B A 4 9
319
ABA
1E929F9F12100A10
0F7C70D00D022FFE
FADDDB38ADE1D1F0
D2E1E02F1CF830D0
AF2FE 09190067620
E00D7370CF1E05D0
DB649FDAF70FE3D0
CF1AD0E1DB 2432 C0
910268 E 929689 E50
C00C077CD707C7F0
79E28D97DD5D1B10
0D1A1ED0CECECE50
F98F9809F9F99D0
0D7DDFF70C07CE0
0
F
88FD8308DCF86DF9
1FDE 9231 EFDFFF0C
71729 AD91D 396219
0C 610722 D3D8A28D
6B2FFF961D8DBDF9
1E1DDD750EFCFC0D
F6154CD39F1919B3
D5D58BE2500C 0702
A3BFFFFED8AF9D07
12FDDD07EF1DDE37
1EFCF48BF192F9F8
25D358FE00CD0D07
599FFF1991FD8F8D
D11DDD0CF5DCFD7E
3FD25FAF1D291ED9
15C3551D0ED70FED
A739FFF2EFDDFAF8
18FEDDDD50CED2DF
第 9 章フロッピーディスク 199
表 9-12 「リスト9-5」の使い方
コマンド
,号
第 2 パラメータ
, -
第3パラメータ
第4パラメータ
リストア !
0
コマンド
—
—
シーク |
1
コマンド
目的シリンダ No . 1
現在のシリンダ No .
ステップ
コマンド
—
ステップ•イン
3
コマンド
ステップ • アウト
4
コマンド
—
—
リードデータ
— ■ | ■■■一 晒, 1
5
コマンド
セクタ No .
ライトデータ
6
コマンド
セクタ No .
_
リードアドレス
~T
コマンド
ダミ-
—
リードトラック
8 —
コマンド
ダミー
ライトトラック
9
コマンド
ダミー
フォースインタラプト
10
コマンド
モーター,サイド,
ドライブナンバー
11
.
r 1
データ
- 1 —
■ ■
D $ = USRO (~)
となっていると, D $ の先頭の文字の ASCII コードとして受け取ることができる。便
利,便利。
では,実行ルーチンの方であるが,たとえば DF 32„ の RESTORE の実行ルーチンで
は , 「LD A , ( DE )」 によって, FDC に送るコマンドを A レジスタに拾い上げている。そ
れをコマンドレジスタ ( CR ) に OUT して, WNBSY をコールする。よ一するにこれは前
述の BASIC で害いたプログラムと同じである。 SEEK , STEP なども同様。
次に DF 5 F „ からの READD (リードデータ), READI (リードアドレス), REDTR (リ
ー ドトラック)の3種混合ルーチンである。恐ろしいことにこれら三つのルーチンは完全
に同じなのである。その結果, READI , REDTR では,必要がないのにセクタ番号を指
定しているのである。実害はないから,大丈夫である。まず , 「CALL SETSCT 」 で A レ
ジスタにコマンドを拾い上げ,なおかつセクタレジスタ ( SCR ) にセクタ番号を OUT して
いる0その先が少々複雑なのだが, BC レジスタにステータスレジスタ (SCR = CR ) のア
ドレスをセットし, EXX で 裏 レジスタにして, BC ' にデータレジスタ ( DR ), HL ' にバッ
ファアドレスをセットしている。ディスクのリード/ライトのためには,二つの違う I / O ア
ドレスに高速にアクセスしなければならないのでこうしたのだが, STR と DR の上位アド
レスはともに 0 F „ だから,どうしても 裏 レジスタを使わなければならないわけではない0結
局は趣味の問題である。その後はコマンドを CR に OUT して,少々待つ。 なぜかよく知
らない力' とにかく待つ。それからはレジスタを表にしたり,裏にしたりしつつ,データ
を受け取るのである。 DF 82„ 番地の RLCA は右にローテートしたステータスを左にローテ
一 卜し直して,元に戻すものである。
次に DF 84„ からの書き込む方であるが, DF 98 H 〜 DFA 9 H 間は,1バイトだけ書くルーチ
ンである。なんでこんなことをしているかというと,ライトトラックのためなのだ。なぜ
かこうしないとライトトラックが成功しないのである。 理由はよ く 分からない;^動け
200 試験に出る XI
ばよいのだ 0 ほかは基本的にリードルーチンと同じである。
さて,リスト 9-5 を実行すると,ドライブ1に対してリストア動作した後 (290 行),第
2トラックへシークし (300 行),第1セクタをリードし (340 行),モーターを OFF す
る0データを読み込むアドレスは, DFFE H 番地からの2バイトに格納されているアドレス
で,リスト 9-5 では E 000„ になっている (260 行の右端)〇 D $ の先頭バイトには,最後に読
み込んだステータスレジスタの値が入っているから,
PRINT ASC ( D $)
で, エラー チェックもできるようになっている。そこで早速リードデータの代わりに,370
行のリードトラックを実行してみていただきたい。 「 D $ = 〜」の代わりに, 「 D 1$ = 〜」と
でもしておくべきだろう。実行後 , PRINT ASC ( Dl $) とすると,「4」が表示されるは
ずである。ステータス表(表 9-9) を見ると,なんと 「LOST DATA 」 である。これは結
局ど 一 ゆ 一 ことかというと,「さっさと読み出さなかったから,データの取りこぼしがある
かもしれないよ」ということである。つまり,早い話が エラーで ある。
話せばわかる! XI では,どうしてもこうなるのである。これは仕方がないのであ
る 0 私のブログラムのせいではないのだ。しかしここにも一筋の光明があるのだ 。XI turbo
ならば , 「LOST DATA 」 にはなるが,充分にデータは読み出せているのである。 turbo 以
外の機種では(全部を確認したわけではないが),データがビットずれを起こしまくっ
て,使いものにならない。
しかし,リードトラックよりも大事なことがあるのだ(と逃(ずる)。まずは TYPE II コ
マンドのフラグについて説明しておく。
m = マルチレコ ー ドフラグ
これは,複数のレコードを一度に読み書きするときに使うフラグである。後で実験す
る。
S = サイドフラグ
これは C フラグといっしょに使うもので,読み出したディスクのサイドが0であるべき
か,それとも1であるべきかを指定する。
E = ディレイフラグ
これは,へッドがディスクに押し付けられたかどうかの信号のサンプリングタイミング
を指定するもの。 XI では意味がない。
c = サイド番号比較フラグ
これは V フラグがトラック(シリンダ)番号を比較するかどうかのフラグであるのに対
して,サイド番号を比較するかどうかのフラグである。しつこく言うが, s フラグといっし
ょに使う。
a 0 = 7 ドレス マーク フラグ
これはライトデータのときだけ指定できるものである。こいつに関してはサンブルを示
した方が早いだろう。
では , TYPE II の実習である。 図 9-5, 9-6, 9-7, 9 - 8である。
まずは m フラグをいじってみる。リスト 9-5 の280行からを図 9-5 のように書き換えて
第9 章 フロッピーディスク 201
いただきたい。まずは 280 行でモーター ON, ドライブは 、、1 :"でサイドは〇番であ
る。リストアして, m= 1 で第 1 セクタから読み始めている。 325 行で,それぞれのステ ー
タスレジスタを表示している。その値は,
リストア命令— 4 (TRACK 00=1)
リードデータ命令—16 (RECORD NOT FOUND )
となっている。モニタに飛んでダンプしてみると,しっかりと16セクタ分が読み込まれて
いるはずである。そこで, BASIC に帰り,
PRINT INP (& HFFA )
として,セクタレジスタの値を表示してみると「17」である0すなわち FDC は m フラグ=
1に従って,第1セクタから第16セクタまでを読み,挙げ句の果てに第17セクタまでを
読もうとしたが,「ない袖は振れない」の法則に従って,当然のごとく失敗して, 「RECORD
NOT FOUND 」 を起こしたというわけである。この m フラグを使うと,連続セクタを読
むという点ではなかなかに高速なのだが,惜しむらくは「いつ終わるのか指定できない」
という欠点があるのだ。それで FDC は「第17セクタはどこだっ!?」と,少しの間捜し回
るので,結局は時間をくってしまう。よって,正しく使うには,必要なだけを読んだかど
うかをチェックしてやって,適当なところで, TYPE IV のフォースインタラブトを使って
コマンドを打ち切ってやらなければならない。なかなかに世話のやける m フラグであつ
た。
図 9-5 m フラグの例
m FLAG
280
D$ = USR0(CHR$(U f &H81))
: , MOTOR ON
290
D0$=USR0(CHR$(0 f &H2))
: •RESTORE
300
D5$=USR0(CHR$(5 f &H90 f 1))
: •READ DATA
310
, D6$=USR0(CHR$(6 f &HA0 l 1))
: 'WRITE DATA
320
D$=USR0(CHR$(11,&H1)}
: , MOTOR OFF
325
PRINT ASC(D0$) f ASC(D5$) f ASC(D6$)
330
KND
4 16 0
次に S , C フラグである。図 9-6 は,平和な例で,280行でサイド0を指定しているか
ら, S = 0 (サイドは0ですか?), C = 1(チェックしてください)によって,ステータス
は0という値になる。この逆が図 9-7 で,280行でサイド0を指定しているのに, S = 1 ( サ
イドは1ですか?), C = 1(チェックしてください)としているので,しっかり16 =
RECORD NOT FOUND が出ている。この場合はデータの読み込みは行なわれない。
図 9-6 S, C フラグの例その 1
S f C FLAG...S=0,C=1
280 D$=USR0(CHR$(11,4H81)) :, MOTOR ON
202 試験に出る XI
D$=USR0(CHR$(11 f &H81)) :, MOTOR ON
D0$=USR0(CHR$(0,&H2)) :, RESTORE
D6$=USR0(CHR$(6 f &HA1 f 1)) : , WRITE DATA
D5$=USR0(CHR$(5 f &H80 f 1)) : , READ DATA
D$ = USR0(CHR$(11 f &H1)) : 1 MOTOR OFF
PRINT ASC(D0$),ASC(D5$) f ASC(D6$)
END
4 32 0
a0 FLAG
,フ イトト フックの
ロッ ピーディスク 203
,リードト
第9
はリード
TYPE IH
MB 8877 の TYPE III
a 0 フラグの実習が図 9-8 である o a 0 フラグ=1で,ライトデータを実行すると,そのセク
夕にデリーテツドアドレスマークが書かれてしまうのだ。具体的にどこかというのは後程
やるのである。これを検出するには,そのセクタを読むだけでよい。図 9-8 のように,ス
テ ー タスレジスタが32となり,第5ビット (RECORD TYPE ) が1になる。この場合に
データはちゃんと読まれるから,特にチェックしない限りデリーテッドアドレスマークが
書かれていようがいまいが,同じことである。では,なぜこのようになっているのかとい
うと,例によって 「 IBM に_いてくれ」なのであった。
図 9-8 ao フラグの例
’MOTOR ON
•RESTORE
# READ DATA
f WRITB DATA
1 MOTOR OFF
$)
S ( C FLAG,..S=l,C=1
280 D$=USR0(CHR$(11 f &H81)
290 D0$=USR0(CHR$(0,&H2))
300 D5$=USR0(CHR$(5 f 4H8A,
310 f D6$ = USR0(CHR$(6 f &HA0 f
320 D$=USR0(CHR$(11,&H1)}
325 PRINT ASC(D0$) f ASC(D5$
330 END
4 16 0
))
))
,ASC(
グの例その 2
290 D0$ = USR0(CHR$(0 f &H2)) :, RESTORE
300 D5$=USR0(CHR$(5 f &H82 f 1)) : , READ DATA
310 'DejrUSROtCHRSte.iHAO,1)) : , WRITE DATA
320 D$=USR0(CHR$(ll f «cHl)) : 1 MOTOR OFF
325 PRINT ASC(D0$) f ASC(D5$) f ASC(D6$)
330 END
4 0 0
0 0 0 0 0 5 0
8 9 0 12 2 3
2 2 3 3 3 3 3
三つがあるわけである。そこでまずは,リードアドレスからである。
リードアドレスとは何かっつうと,ディスクに書かれている 「 ID フィールド」と呼ばれ
る部分を読み出すということである。正しくフォーマットされたディスクには,各セクタ
ごとに ID フィールドとデータフィールドが1個ずつあるのだ。念のために言うと,「フィ
ー ルド」とは 「領域」 とか 「区画」 という意味である。要するに平たく言えば, ID フィー
ルドとはセクタの「ラベル」みたいなもので,データフィールドは「中身」である。
さて, ID フィールドの読み方であるが, リスト 9-6 である。縁起ものだから,リスト
9-5 と同じ形式で載せておくことにする。 RUN した後にモニタに飛んで, E 000 H からをダ
ンプすると最初の6バイトが大体 図 9-9 のようになっているはずである。この内訳は,
• 0バイト目=シリンダ番号
• 1バイト目=サイド番号
癱2バイト目=セクタ番号
• 3バイト目=セクタ長 (0 〜 3)
• 4ハ♦イト目 = CRC 上位
• 5ハ♦イト目 = CRC 下位
となっている。これらはすべて,フォーマット時に書き込まれたものである。セクタ番号
は,最初に出会ったセクタのものである。よって,このままでは1〜16番のうちどれが来
るかは運まかせである。
セクタ長は,
0 —1 セクタ当たり128バイト
1—1 セクタ当たり256バイト
2 —1 セクタ当たり512バイト
3 —1 セクタ当たり1024バイト
リスト 9-6 ID フィールドを読み出す場合の「リスト9-5」の変更点100〜270行は同じ
280
D$=USH0(CHR$( 11 f &H 81 ))
1 MOTOR ON
290
D$=USR0(CHR$(0 f &H2))
1 RESTORE
300
, D$ = USR0(CHR$<1 , &H1E , 2 , 0 > >
'SEEK
310
•D$=USR0(CHR$(2•&H3A> >
f STEP
320
, D$ = USR0(CHR$ < 3 , &H5A))
# STEP IN
330
, D$ = USR0(CHR$(4 f &H7A))
'STEP OUT
340
, D$ = USR0(CHR$<5,&H80,1> >
•READ DATA
350
# D$=USR0(CHR$(6 f 4HA0,1))
1 WRITE DATA
360
D$=USR0(CHR$(7 f &HC0 f 1))
•READ ADD.
370
, D$=USR0(CHR$(8 f &HE0 l 1))
f READ TRACK
380
, D$ = USR0<CHR$(9,&HF0,1> >
•WRITE TRACK
390
, D$=USR0(CHR$(10 f &HD0))
f FORCE INT.
400
D$=USR0(CHR$(11 f &H1))
1 MOTOR OFF
410
END
図 9-9
旧フイ ー ルドの 内容
: E000=00 00 02 01 AF 5F 00 00 /..
• % 1 •籲
204 試験に出る XI
を指定している。普通は1セクタ256バイトだから「1」になっているはずである。最後
の2バイトの CRC は,早い話がチェックサムみたいなものである。読み出すときのチェッ
ク用で,一定の方法で計算が行なわれる。 FDC が勝手に計算してくれるので,另 IJ に心配す
る必要はない。もちろん,計算が合わなければ , 「CRC ERROR 」 が発生するわけであ
る。
というところで,もう一度図 9-9 を見ると,最初の2バイトは 00 H , 00 H で,つまりは第
〇シリンダの第0サイドなのである。そして,第2セクタに最初に出会った。そのセクタ
のタイプは1だから,ありふれた容 M 256 バイトの フォー マットである。最後の2バイト
の CRC の AF h , 5 F h は, CRC というわけである。
ここでわれわれその筋探検隊は,フロッピーディスクの深淵へと向かうのである。それ
はど 一 ゆ一ことかというと,「ディスクの中で各セクタはどのように並んでいるのだろう」
という疑問である。普通に考えるなら,1,2, 3, . ’ 16であるが,別にそうでなく
てもよいはずである。そこで考えてみると,たしか TYPE I のコマンドを実行した直後な
ら INDEX ホールを検出できる っつう ことに思い当たるのであった。よって,インデック
スホールを検出した後で,リードアドレスを立て続けに16回行なえば1周分の各セクタの
ID フイールドが読めてしまうのである。
しかし,悲しいことに BASIC でそれをやっても速度が追っつかないのである。結局はま
たもや機械語を組まなければならない。う一むとつぶやきつつ リスト 9-7 と リスト 9-8 で
ある0
リスト 9-7 旧フイールドの連統読み込み
0FF8
0FF8
0FFB
DE00
DE01
DE04
DE06
DE08
DE0A
DE0B
DE0C
DE0D
DE10
DE13
DE14
DE16
DE18
DE1A
DE1B
DE1D
DE1F
DE20
DE22
DE23
DE25
DE26
DE28
DE29
DE2A
F3
01 0FF8
ED 78
E6 02
28 FA
1A
57
D9
01 0FFB
2A DE37
D9
3E C0
ED 79
3E 07
3D
20 FD
ED 78
0F
30 0B
0F
30 F8
D9
ED 78
77
23
D9
6r
• Z80
.PHASE
0DE00H
EQU
0FF8H ;COMMAND REG.
STR
EQU
0FF8H ; STAT- REG-
DR
EQU
0FFBH ;DATA REG.
START :
DI
t
LD
BC f CR ; CR=STR
WINDEX :
IN
A t (C)
AND
02H ;CHECK INDEX
•
JR
Z,WINDEX
•
LD
LD
A f (DE)
D,A ; D=COUNTER
•
EXX
LD
LD
EXX
BC,DR ;DATA REG.
HL f (BUFAD) : BUFF
AGAIN :
LD
A.0C0H ;READ AD. COM
OUT
(C) f A ;SEND COMMAND
LD
A,7
WAIT :
DEC
A
RED1:
JR
IN
NZ f WAIT
A, (C)
RRCA
;CHECK BUSY
JR
NC.RED2 ;END READ
RRCA
: CHECK DATA R1
JR
NC,RED1;NO REQ.
EXX
IN
LD
INC
EXX
A f (C)
(HL) f A ;STORE DATA
HL
第 9 章 フロッビーディスク 205
リスト 9-7 は,まず FDC のステータスレジスタを IN して,第1ビット ( = INDEX ) が
1になるまで待つ。その後,指定された回数だけバシバシとリードアドレスを実行して,
最後の1バイトを読んだときのステータスといっしょにメモリに格納する0説明はこんな
ものでよいだろう。リスト 9-8 を見ていただきたい。これはリスト 9-7 の使い方である。
100〜270行には,リスト 9-6 ( 9-5 ) の100〜270行を必要とする0
やっていることは単純で,まず360行でモーターを ON して,370行でとりあえずリスト
アを実行してへッドを第0トラックへ持ってくる。380行ではお望みのトラックまでシー
クしている。トラック番号は TR に入っている。そこですかさず,
D $ = USR 1( CHR $ (読み出す回数))
である0最後のステータスもメモリに格納するから,1回当たり7バイトのデータが取れ
るわけである。400行からはそれを表示している。くれぐれも注意するが, USR 1 の直前に
は TYPE I のコマンドを実行しておくこと。さもなくばリセットスイッチのお世話にな
ってしまうのである。
ここで研究発表をするわけだが,それは 図 9-10 である。 HuBASIC の場合は平和に1
〜16が順に並んでいる。 XI CP/M は,第0と第1シリンダは HuBASIC と同じ,第2シ
リンダからは,図 9- 10に害いてあるようになっている。 MZ - 2000/2200の CP/M では全シ
リンダにおいて図 9-10 のようになっている。
206 試験に出る XI
図 9-10 セクタの並び方
HuBASIC
12 3 4 5 6 7 8 910111213141516
XI CP/M (TRACK 2-39)
114118 5 21512 9 6 3161310 7 4
MZ CP/M
13 5 7 9111315 2 4 6 810121416
そこで,ど一してこうなっているかである。
一般には第1セクタを読み書きした後は第2セクタを読み書きするわけであるが, CP /
M のようにハードウェアと密着していないソフトウェアなどは,その2回の読み書きの間
に別の処理が入り,その間にディスクが少々回ってしまうのである。つまり,1〜16まで
順に並んでいると,「第1セクタを読み終え,次に第2セクタを読もうとしても,すでに第
2セクタはへッドの位置を通り過ぎてしまっている」のだ。そうなると,ディスクがもう
1回転するまで待たねばならない。前述のように,5インチや3インチの 2 D , 2 DD のディ
スクは1分間に300回転,すなわち1秒間に5回転しているから,1周分といえば 0.2 秒
である。はっきり言って,これはとても長い時間なのだ。そこで,あらかじめ第1セクタ
と第2セクタの間を離しておくわけである。もちろんこれは第2セクタと第3セクタの間
でも同じことである。第 n セクタから何個目に第 n + 1セクタがあるかを数えてみると(も
ちろん 16 — 0と巡回するんだよ),
HuBASIC — 1個
XI CP/M — 5 個
MZ CP/M — 8個
となっている。この1,5,8,の数字はスキューファクタと呼ばれる。これと同じよう
な意味を持つものにインターリーブファクタというものもあって,これは隣り合ったセク
夕番号の差である。
HuBASIC ->2-1 = 1
XI CP/M —14- 1=13
MZ CP/M — 3- 1= 2
となる 。 MZ CP / M の場合は 15 — 2, 16 — 1の所で乱れている点に注意。ま,ど一でも
いいけどね。
この先は少々その筋の話になるのだが, その筋のディスクにその筋すると, その筋
のセクタ番号があったりする。たとえば,第0セクタとか,第17セクタである。さらには
第1セクタが26個あったりなどの 凶器攻擊も ある。ここらへんのことは自由研究として
おいて,私は次にリードトラックとライトトラックを説明するのである。
Xl/Xl turbo でリードトラックを実行すると,どちらでも LOST DATA エラーが起き
るが, turbo ではデータが使いものになる理由を説明する。これはディスクのインターフェ
イスの性能に関係するのである。だから turbo に CZ -500 F や CZ -800 F を接続してリード
トラックを実行しても,使いものになるデータが読めるのである(所々でビットずれは起
第9章フロッピーディスク 207
こすが,それはいかなる場合でも起こることである)。これは,どうやら VFO というクロ
ックビットとデータビットを分離する回路の性能に関係するらしい。 turbo はその回路の
性能がいま一なので,取り出したデータは使えるが LOST DATA エラーが発生し , turbo
以外は,いま三なのでエラーが起きるだけではなく,データも狂いまくるわけである。し
かし,リードトラック以外では問題が起きないので,あんまり強く文句を言うわけにはい
かない-が,私は文句を言うぞっ!
「文句,文句,文句,文句,文句」
では,ライトトラックを説明する。そうすればリードトラックも自動的に理解できる。
ライトトラックの機能は,言うまでもなく,ディスクに物理フォーマットを書き込むこと
にある。物理フォーマットは,1トラック(片面分)当たり約6.25 K バイト (6400 バイト)
のデータを,ライトトラックコマンドを使ってディスクに書き込むことにより指定され
る。その 6.25 K バイトの内訳は,「はいっ,ここからここまでは ID フィールドですよ。そ
いで,ここからの256バイト分はデータです。第1セクタの次には第2セクタが続きます」
などということの指定である。では早速であるが, 「 ISO タイプ5.25インチフォーマッ
卜」に使う 6.25 K バイト分のデータを 表 9-13 に示す。この表は,参考文献10に大いにお
世話になっている。
さて,実はこいつはなかなかの喰わせものなのである。よって説明する。
まず,表 9-13 から分かるようにフォーマットは三つの部分に分かれている。 GAP 1 と各
セクタのフォーマット(複数個ある)と GAP 4 である0つまり,1トラックのフォーマッ
卜は GAP 1 で始まり,最後に GAP 4 で終わるということである。しかし主役は,その間に
挟まれた「セクタのフォーマット」である。1トラック(片面)に,256バイトの容 M のセ
クタが16個ある普通のフォー マッ トでは,
GAP 1, 各セクタ X 16, GAP 4
となっているわけである。
では,その普通のフォーマットについて,インデックスホールの位置から順に説明す
る。
• GAP 1
インデックスホールの位置から, 4 E H の相当するデータが32バイト分である。このほか
にも GAP 2, 3, 4があるが,いずれもフロッピーディスクドライブのばらつき(回転速度
のズレなど)に対処するためのものである。
籲最初のセクタ(第1セクタとは限らない)
ここから表 9-13 の下の部分へ行く。
セクタは次の部分からなる。
Sync
00 H が12個書かれている。これは同期を取るためのもの。
AM 1
ID ADDRESS MARK である。これは3個の Al „ (実はちょっと違う)と1個の FE H か
らなる。 A 1 H は,普通のデータではなく,ミッシングクロック (Missing Clock ) を含んで
208 試験に 出る XI
表 9-13 ISO タイプ5.25インチフォーマット
1 セクタ当たりの 容置
U - ~- - —■ — ■
GAP1
各セクタのフォーマット
GAP4
256 バイト
4Emx32
L I
»■_ 1 ■ _ ■ 1
4E„x266
512 バイト 1
[- ■ 1 1
4E„x296
1024 バイト
実際のデータ ( MB8877 用)
1 ■ 1
下を見よ
(第 t シリンダ,第 s サイド,第 n セクタ用のフォーマット:実際はこれが複数個並んでいる)
いる。これは英語的な言い方で,実にその筋なので言い直すと,よ一するにクロックビッ
卜が1個足りないのだ。 Al „ は2進数だと,
10100001„
となり,これは MFM 記録方式の規則から,0と0の間にクロックビットが入るので,普
通ならば,
1010 0 0 01
T T T
の3か所にクロックビットが入るはずである。ところがどっこい,この A 1 H の場合は,真
ん中のクロックビットがないのである。だから表 9-13 の下の部分では ( Al „) のよう
に,カッコでくくってある。これは後で出てくる AM 2 でも同じである。 ( A 1 J の後の FE „
は普通の FE „ である。さて,下の方に「実際のデータ」という櫊があるが,ここに 「 F 5 h 」
とか書いてある。つまり MB 8877 にこのクロックビットの抜けている ( Al „) を書かせる
ときは, Al „ の代わりに F 5„ を送ってやればよいのだ。 MB 8877 はライトトラックを実行中
に, F 5 h , F 6 h , F 8 h などが送られてくると特別扱いするのである。この点については後で
まとめてやる。
ID
ここには,シリンダ番号,サイド番号,セクタ番号,セクタのタイプ(大きさ)などが
壽かれている。リスト 9-6 の「リードアドレス」で読み出したデータのうちの最初の 4 バ
イト分である。
第 9 章 フロッピーディスク 209
CRC
この CRC は, AMI の最後の FE „ と ID の計5バイトに対する CRC である。 MB 8877 で
は F 7„ を1バイト送っただけで,2バイトの CRC を勝手に計算して書いてくれる。
GAP2
GAP 1 と同じようなもの。
Sync
さっき説明した。
AM2
ここにある3個の ( Al „) は AM 1 と同じである。その次に FB „ が来るのだが,これは先
程やったライトデータの a 0 フラグと関係しているのだ。普通は FB H (DATA MARK ) な
のだが, a 0 = 1でライトデータを行なうと F 8 h (DELETED DATA MARK ) になってし
まうのである。
DATA
普通読み書きするのはこの部分である。
CRC
AM 2 の FB „ (もしくは F 8„) とデータを併せた部分の CRC である。
GAP3
GAP 1, 2と同じ。
これで1セクタ分が終わりである。
• 2〜16番目のセクタ
これは「最初のセクタ」と基本的に同じ形式0ただセクタ番号だけが違う。
• GAP 4
4 E H が,インデックスホールまで続いているのである0
以上がトラック(しっこいようだが片面分)のフォーマットである。途中で, 「 F 5 h を送
ると ( Al „) が書かれる」などと書いたが,そのようなことになる値の一覧表を表 9-14 に
示す。表 9-14® の中では ( C 2„) とかが出てくるが,これは 「 IBM タイプフオーマット」
の中で使われるものなのである。実は5.25インチのフロッピーディスクのフォーマットに
は,メジャーなものが2とおりあるのだ。二っのフォーマットの違いは大きくはなく,表
9-15 を表 9-13 の代わりに使うと 「 IBM タイプ」になる。見て分かるとおりに,これは
GAP 4 を短くして GAP 1 を増やし,さらに GAPO とか INDEX MARK とかを入れてしま
ったものである。ただし全体のバイト数は変わっていないことに注意していただきたい。
二っのフォーマットの違いは,参考文献10によると, ISO タイプの方がエラー発生の可能
性が減るということらしい。たしかに表を見比べると IBM タイブは GAP を短くして
INDEX MARK などというものを入れているのだから, FDC がどちらのフォーマットも
読めるのであれば,ゆとりのある ISO タイプの方が有利であろう。ちなみに HuBASIC と
S-BASIC ( MZ - 200 0) は ISO タイプ, MZ -2000 の CP / M は大胆にも IBM タイプのよう
である。
210 試験に出る XI
マツ ト)時のデータの意味
MB8877/76
に送るデータ
OOh
ディスクに
害かれるデー
OOh
i
普通のデータ
F4h
-- - ■ - --
一夕をプ
F6h
F7h
F8h
F9h
FA
FB»
(C2h :
CRC
F8h
F9h
FA
FB»
FDh
FDh
.AM2 の前提 (CRC
INDEX MARK の前提 (CRC
内部で計算された CRC (2 バ
AM2 の中では DELETED DATA MARK
普通のデータ
••は DATA MARK
(C2h)X3 の後で INDEX MARK
普通のデータ
•は ID ADDRESS MARK
普通のデータ
MB8877/76 _
に送るデータアータ
F7m
F8h
F9h
FA
FBh
FC
FDh
FE
CRC
F8h
F9h
FA
■
FBh
FC
FDh
FE
内部で計算された CRC (2 バ
AM2 の中では DELETED DATA MARK (CRC ジ ! ネトタをプリセットす 4)
DATA MARK (CRC
INDEX MARK (CRC
一夕をブ
•一夕をプ
ID ADDRESS MARK (CRC
普通のデータ
第 9 章フロッピーディスク 211
表 9-15 IBM タイプ5.25インチフォーマット
DF 16
D1 12
84 DF
ED 79
59 01
01 F8
01 FB
0B 0F
DF 01
ED 79
ED 79
23 D9
1A 01
FE 01
3D 20
DF F1
アドレス
-マット用データを作る
1220 1
1230 DUMMY=INP(&HFFF)
1240 OUT &HFFC,&H80+DN:GOSUB M WNBSY
1250 OUT &HFF8 f &H 0 : GOSUB”WNBSY”
1260 OLDTR=0
1270 RESTORE ## TYPE #f : READ SECTORTYPE
1000
1010
1020
1030
1040
1050
1060
1070
1080
1090
1 100
1110
1120
1130
1140
1150
1160
1170
1180
1190
1200
1210
CLEAR &HC000
MEM$(&HDF00 f 16)=HEXCHRS( M D51A 13 D5
MEM$(&HDF10 f 16)=HEXCHRS( f, Dl F3 CD 19
MEMS(&HDF20 f 16)=HEXCHR$( ff 55 DF 55 DF
MEMS(&HDF30 f 16)=HEXCHR$( ff C6 DF 1A 01
MEMS(&HDF40 f 16)=HEXCHR$( ff 23 5E 01 F9
MEM$(&HDF50 f 16)=HEXCHR$( M 79 CD D2 DF
MEMS(&HDF60 f 16)=HEXCHR$( M EA DF 01 F8
MEM$(&HDF70 f 16)=HEXCHR$( M E4 DF ED 78
MEM$(&HDF80 f 16)=HEXCHRS( l# 18 F0 07 C9
MEMS(&HDF90 t 16)=HEXCHR$( M DF D9IE 00
MEMS(&HDFAO f 16)=HEXCHR$( M 98 DF 18 06
MEMM&HDFB0,16)rHEXCHR$( ft 30 F8 D9 7E
MEM$(&HDFC0 f 16)=HEXCHRS( #t ED 79 CD D2
MEM$(&HDFD0 f 16)=HEXCHRS( M DF C9 C5 06
MEM$(&HDFE0 f 16)=HEXCHR$( M F6 79 Cl C9
MEM$(&HDFF0 f 16)=HEXCHR$( M 0F ED 51 F5
DEFUSR0=&HDF0O
DEFINT A-Z:DIM VAR(40) f SQ(40
211A
DF FB
5F DF
F8 OF
0F ED
C91A
0F D9
0F 30
CD EA
16 02
D9 7E
ED 79
DF C9
20 10
3E 07
CD D2
DN=1
AD = «cHE000
PRINT ,f MAKING DATA
’ ドライブ *
• フオ•マツ
GOSUB #f MAKE-
号
卜用デ
FORMAT
-夕の
• フ .
1280 1
1290 FOR CYLINDER=0 TO 39
1300 GOSUB M SEEK tf : 0LDTR=CYL1NDER : 'SEEK
1310 FOR SIDE=0 TO1
1320 OUT &HFFC.&H80 OR DN OR SIDE 拿 :•* 表の設定
212 試験に出る XI
1セクタ当たりの容置
GAP 0
Sync
" - - ■ -- "T
INDEX MARK
GAP 1
各セクタの
フォーマット
GAP 4
256バイト
4EhX80
00hX12
(C2h)x3
① X 16
4 EhX 152
512バイト
② X 9
4 EmX 132
f ■■ ■ ]
10以バイト
実際の データ
同上
け — x
同上
F6hX3
同上
r=y . 表 9H3 の下の
|oJ 上 冊分を見よ
同上
そこで,どど一んとディスクをフォーマットするブログラムが リスト 9-9 である(注釈
を見ると turbo BASIC だということが分かるが,実際は turbo BASIC では動かないの
で注意)。1010〜1170行は例の機械語部分(リスト 9-5 の110〜270行)をリナンバーした
ものである。二,三説明すると,まずこのブログラムは CZ -8 FB 01 でなければ動かな
い。それから1340〜1380行は, USR 0 を実行してエラーが起きた場合に5回まで試してみ
るためのものである。このプログラム(機械語部分)だと,どうもタイミングがいまいち
らしく,変数 STAT に返ってくるステータスがたまに「2」になってしまう。これは
「DATA REQUEST だけ」ということなのだ。 「 BUSY 」 にはなっていないのである〇困
ったものだ。しかし,たまにだけだから許すことにしたのである。次に1860〜1900行であ
るが,これはシリング番号,サイド番号,セクタ番号,セクタ容 M , のメモリへの書き込
みを行なっている0データに対応するアドレスはサブルーチン '' MF - SUB " によって配歹 IJ
VAR (〜)に入れられてあるのだ。 RUN すると,ドライブ''1:"に入っているディス
クを,のんびりとフォーマットする0各トラック(片面)ごとにステータスを表示し,〇
でなかったら数度 (5 回まで)リトライするようになっている。
リスト 9-9 ディスク フォーマッ トブログラム (turbo BASIC では動かない)
BFF6DDD9E2FF20 A0
EDD5ECCDFC00D2 FE
65C3F993ADB8D1 10
55B20C 72210 FC8 00
3FFE8FD7FF0106 60
2DD7FDE70D30FE 50
EC4B1298B4FA7F 30
538E0DD7FA01B4 20
9FF91DFD1 28998 E0
1DDC5CDE0C7C77 70
F2FFD9E992D7DD B0
535DE7FDDAE0EE E0
79F2FDA8F890FF 90
8EDD0E2F07DFO0 C0
09FDBFF08D38C8 D9
OC5CF003FE21FF FC
る
こ
ド
I
モ
D
D
N
〇
ァ
2
•夕卜
D I ス
2 モリ
1330 GOSUB"SET-FORMAT"
1340 TRY=0
1350 IF TRY>5 THEN BEEP •• PRINT •• PR I NT” ERROR GOTO 1430
1360 GOSUB”WTR" : •WRITE TRACK
1370 PRINT STAT ; ft : M ; : f PRINT STATUS
1380 IF STATO0 THEN TRY=TRY+1 : GOTO1350 : 1 RETRY
1390 NEXT
1400 NEXT
1410 , DMA$ = HEXCHR$( f# 83 M ) : GOSUB..SETDMA"
1420 PAUSE 1
14 30 OUT &HFFC f &H 3 AND DN: 1 モータ ー OFF
1440 DUMMY=INP(&HFFF) •• • 2 D • 2 D D モードにする
1450 END
1460 1
1470 LABEL f# SEEK ff
1480 OUT &HFFB,CYLINDER : •データレジスタ
1490 OUT &HFF9.0LDTR :•トラックレジスタ
1500 OUT &HFF8 t &H10 •• 1 シークコマンド
1510 GOSUB ft WNBSY M
1520 RETURN
1530 1
1540 LABEL M WNBSY ff
1550 CT=0
1560 IF CT> 1000 THEN PRINT"DISK? ••: GOTO 1410
1570 IF INP(&HFF8) AND &H81 THEN CT=CT+1:GOTO 1560
1580 RETURN
1590 #
1600 LABEL tf SETDMA M
1610 FORI =1TOLEN(DMA $) : OUT 1F80 f ASC(MID$(DMAS f I f 1)) : NEXT
1620 RETURN
1630 1
1640 LABEL ft WTR ,f
1650 D2$=USR0(CHR$(9 9 &HF0 9 1)) : STAT=ASC(D2$) : RETURN
1660 DMA$=HEXCHR$( M 83 79 00 C0 AF 2814 28 8D FB 0F 92 CF 05 CF 87”>
1670 GOSUB"SETDMA”
1680 OUT &HFF8 f &HF0 : 1 ライトトラックコマンド
1690 S=INP(&HFF8) : IF S AND 1 THEN 1690
1700 STAT=S:RETURN
•1710 1
1720 LABEL"MAKE-FORMAT”
1730 VAR{0)=0: f CLEAR COUNTERS
1740 REST0RE"GAP1":GOSUB”MF-SUB” : 'MAKE GAP1
1750 RESTORE 11 TOTAL SECTOR ••: READ TSEC : •HOW MANY SECTORS ?
1760 FOR SECT=1 TO TSEC
1770 RESTORE”SECTOR” : GOSUB"MF-SUB.. : 1 MAKE SECTOR FORMAT
1780 NEXT
1790 RESTORE..GAP4” : GOSUB”MF-SUB" : 1 MAKE GAP4
1800 RESTORE"SQUE"
1810 FOR SECT=1 TO TSEC
1820 READ SQ(SECT)
1830 NEXT
1840 RETURN
1850 1
1860 LABEL #f SET-FORMAT ••: f SET ID FIELD
1870 FOR P=1 TO VAR(0)
1880 MEM$( VAR(P) f -4 ) =CHR$ (CYLINDER f SIDE f SQ ( P) f SECTORTYPE)
1890 NEXT
1900 RETURN
1910 1
1920 LABEL"MF_SUB M
1930 READ C:IF C=0 THEN RETURN: 1 n Byte f DATA ) ケイシ筹
1940 READ D$:IF D$<>"!" THEN D=VAL(D$) : GOTO 1970
1950 f !.-MEANS "VARIABLE DATA”
1960 VAR(0)=VAR(0)+1 : VAR(VAR(0))=AD : D=99: f INC COUNTER, STORE ADDRESS
1970 IF C く 256 THEN MEM$(AD f C)=STRING$(C t D):AD = AD+C : GOTOl930
1980 MEM$(AD f 255)=STRING$(255 f D) : AD=AD+255 : C=C-255 : GOTOl970
1990 1
2000 し ABEL”GAP1”
2010 DATA 32 f &H4E f 0
2020 LABEL”SECTOR"
2030 DATA 12,0, 3 f «tHF5 t 1 f &HFE f 4 f !
2040 DATA 1 f &HF7 f 22 f &H4E f 12,0 f 3 f &HF5 f 1 f &HFB f 256 t &HE5 f 1 f &HF7 f 54 f &H4E f 0
2050 LABEL”GAP4” : 1 " "
2060 DATA 266 t &H4E t 0 ノく -!!! !!! !!!
2070 LABEL"TOTAL SECTOR"
2080 DATA 16 ソ く -!!!
2090 LABEL ff SQUE ft
2100 DATA l 9 2 f 3 f 4 9 5 f 6 f 7 l 8 9 9 f 10 f ll l 12 9 13 9 14 f 15 f 16
2110 LABEL tf TYFE M
2120 DATA 1 : , く -!!! 1 SECTOR 256 Byte つうことでん力 < な
さて,このプログラムは実にその筋なので,2000行から後を リスト 9-10 と替えると,な
んと1セクタ512バイトのフォーマットとなるのである。さらには リスト 9-11 に替える
と,1セクタが1024バイトになってしまうのだ。ディスク1枚で 400 K バイトだぞ。さら
に追い擊ちだっ。3インチドライブや XI turbo などのドライブ ( CZ -800 F /801 F 以外)だ
とへッドは第42シリンダまで動くから,1290行の「39」を「42」にするとディスク1枚で
430 K バイトだだだだだっ! 持ってけドロボーなのである。これは「オーバートラック」
と呼ばれるヒネリ技である。もちろん第40シリング以降の書き込み,および書き込ま
れたデータには,シャープ株式会社は何の保証もしない「その筋トラック」であるから覚
悟して使うように。
リスト 9-10 ディスクフォーマットプログラム 1 セクタ = 512 バイト用変更点
2000
LABEL"GAP1"
2010
DATA 32.&H4E, 0
2020
LABEL"SECTOR"
2030
DATA 12 f 0 f 3.&HF5,1 f &HFE,4 f !
2040
DATA 1,&HF 7,22 , &H4E , 12,0,3 , &HF5,1 , &HFB,512 , &HE5,
1 ,& HF7,84,&H4E,0
2050
LABEL M GAP4 M : 1 れ
A
2060
DATA 296 , &H4E,0 : ,く-!!! !! !
1 曹曹
• • •
2070
LABEL n TOTAL SECTOR"
2080
DATA 9 : , <-!!!
2090
LABEL N SQUE V,
2100
DATA 1 , 2,3,4, 5,6,7,8,9
2110
LABEL"TYPE"
2120
DATA 2 : , く-!!! 1 SECTOR 512 Byte つぅこ
とでんがな
リスト 9-11 ディスクフォーマットブログラム 1 セクタ =1024 バイト用変更点
2000 LABEL M GAP1 M
2010 DATA 32,&H4E,0
2020 LABEL"SECTOR"
2030 DATA 12,0,3 f &HF5 f 1 f &HFE f 4 f !
2040 DATA 1 # &HF7 f 22 ,&H4E,12,0,3 f &HF5 f 1,&HFB ,1 024,&HE5 ,1 f &HF7 f 116 9 &H4E 9 0
2050 LABEL"GAP4" : 1 へ れ
2060 DATA 208 f &H4E v 0 : , く -!!! !!! !!!
2070 LABEL"TOTAL SECTOR"
2080 DATA 5 : , く -!!!
2090 LABEL”SQUE"
2100 DATA 19293 v 4 9 5
2110 LABEL"TYPE"
2120 DATA 3 :’ く -!!! 1 SECTOR 1024 Byte つうことでんがな
なお,このブログラムには仕掛けがしてあるので, turbo の場合は少々変更すると DMA
を使ったディスクフォーマットルーチンになる。それについてはまた後程。
次に リスト 9-12, 9-13 である。これは G - RAM — ディスク間の直接読み書きルーチン
なのだ。リスト 9-12 では,書き込みルーチンがなかなか味わい深い。この部分では , DATA
REQUEST 信号に素早く応答できるように A ' (裏レジスタ)に,次に書き込むべきデータ
を用意してあるのだ。タイミングが難しいケースにおける,いわゆる一つの解決例になっ
ている。
214 試験に出る XI
) スト 9-12 G - RAMh ディスク直接 R / W ブログラム
in
.Z80
.PHASE
0DD00H
0FF8
EQU
0FF8H
COMMAND REG,
0FF8
STR
EQU
0FF8H
STAT. REG.
0FF9
TR
EQU
0FF9H
TRACK REG.
0FFA
SCR
EQU
0FFAH
SECTOR REG.
0FFB
DR
EQU
0FFBH
DATA REG.
0FFC
MSDR
EQU
0FFCH
MOTOR,SIDE,DRIVE# SF 丄 EC
DD00
D5
START :
PUSH
DE
DD01
DD
El
POP
IX
;IX = DF.
DD03
DD
66
01
LD
H 9 (IX+1)
; H=COMMAND
DD06
DD
6E
02
LD
L t (IX + 2>
••L=SECTOR 参
DD09
16
FB
LD
D f LOW(DR)
DD0B
1E
F8
LD
E f LOW(STR)
DD0D
D9
EXX
DD0E
DD
4E
04
LD
C t ( 1X^4 )
DD1 1
DD
46
05
LD
B, (1X^5)
: BUFF ADD.
DD14
ED
78
IN
A, (C)
••GET FIRST 1 Byte
DD16
08
EX
AF.AF*
;A*=FIRST DATA
DD17
D9
EXX
DD18
DD
7E
00
LD
DI
A, (IX + 0)
••GET •R* or
DD1B
F3
•
DD1C
FE
52
•
CP
JR
DD1E
28
0A
•
Z,READD
DD20
FE
57
t
CP
JR
DD22
28
2C
•
Z.WRITD
DD24
DD
36
00 FF
•
LD
El
(IX+0),0FFH ;SET ERROR
DD2B
FB
DD29
C9
•
RET
DD2A
READD :
DD2A
CD
DD77
RAGAIN :
CALL
SETFDC
••SET SCT#,COM.
DD2D
ED
78
RED1 :
IN
A, (C)
••GET STATUS
DD2F
0F
RRCA
;CHECK BUSY
DD30
30
0E
JR
NC.RED2
;END READ
DD32
0F
RRCA
;CHECK DATA REQ.
DD33
30
F8
•
JR
NC.RED1
: NO REQ.
DD35
4A
•
LD
IN
C t D
; BC=DR
DD36
ED
78
A, (C)
;READ DATA
DD38
D9
KXX
DD39
ED
79
OUT
(C) ,A
;STORE DATA
DD3B
03
INC
BC
••NEXT ADD.
DD3C
D9
EXX
DD3D
4B
LD
JR
C f B
; BC=STR
DD3E
18
ED
•
RED1
DD40
07
RED2 :
RLCA
: BACK STAT
DD41
DD
77
00
LD
<1X^0) ,A
;STORE STAT
DD44
E6
9F
AND
9FH
;CHECK ERROR
DD46
20
06
JR
NZ.RED3
;QUIT READ
DD48
2C
INC
L
;IX+2=SCTNO
DD49
DD
35
03
DEC
(IX+3>
;IX+3=COUNT
DD4C
20
DC
JR
El
NZ,RAGAIN
DD4E
FB
C9
RED3 :
DD4F
•
RET
DD50
WRITD :
DD50
CD
DD77
WAGAIN :
CALL
SETFDC
;SET SCT 参, COM.
DD53
ED
78
WRT1 :
IN
A,(C)
DD55
OF
RRCA
;CHECK BUSY
DD56
30
10
JR
NC.WRT2 :
;END WRITE
DD58
0F
RRCA
;CHECK DATA REQ.
DD59
30
F8
•
JR
NC,WRT1 ;
;NO REQ.
DD5B
4A
•
LD
EX
C f D
;BC=DR
DD5C
08
AF,AF f
; A f =DATA
DD5D
ED
79
OUT
(C) f A
;WRITE DATA
DD5F
D9
EXX
DD60
03
INC
BC
;INC ADD.
DD61
ED
78
IN
A, (C)
;GET NEXT DATA
第 9 章 フロッピーディスク 215
AF f AF f ; A f =NEXT DATA
7D
01OFFA
ED 79
01 0FF8
ED 61
3E 07
3D
20 FD
C9
1 DD63
DD64
DD65
DD66
DD68
DD69
DD6C
DD6D
DD6F
DD70
DD73
DD75
DD76
DD77
DD78
DD7B
DD7D
DD80
DD82
DD84
DD85
DD87
リスト 9-13 G-RAMh デイスク直接転送ブログラム
270 ’100 - 270 V • ウハ V スト 9-5 ノそノヲツカウノテ•アル
280 CLEAR &HDD00
290 MEMS(&HDD00 1 16 ) =HEXCHR$ ( f# D5 DD HI DD 66 01 DD 6E 0216 FB IE F8 D9 DD 4E
300 MEMS(&HDD10 f 16)=HEXCHRS( ,# 04 DD 46 05 ED 78 08 D9 DD 7K 00 F3 FE 52 28 0A
310 MEMS(&HDD20 f 16)=HEXCHRS( ft FE 57 28 2C DD 36 00 FF FB C9 CD 77 DD ED 78 0F
320 MEM$(&HDD30 f 16)=HFXCHRS( #f 30 OK 0F 30 K8 4A ED 78 D9 ED 79 03 D9 4B 18 ED
330 MEM$(&HDD40 f 16)=HEXCHRS( M 07 DD 77 00 E6 9F 20 06 2C DD 35 03 20 DC FB C9
340 MKM$(AHDD50 f 16)=HEXCHR $("CD 77 DD ED 78 OF 3010 OF 30 F8 4A 08 ED 79 D9
350 MEM$(&HDD60 f 16)=HEXCHR$( f 03 ED 78 08 D9 4B 18 EB 07 DD 77 00 B7 20 06 2C
360 MEM$(&HDD70 t 16) =HEXCHR$ ( t# I)D 35 03 20 DB KB C9 7D 01 FA 0F ED 79 01 F8 0F
370 MEM$(&HDD80 t 16)=HEXCHHSC # EI) 613E 07 3D 20 FD C9 00 00 00 00 00 00 00 00
380 DFFUSH2=&HnD00
390 1
4 00 GOSUB .GSMP じ •
410 D$ = USR0(CHR$(11 f AH81)) : 1 MOTOR ON
420 DS=USR0(CHR$(O f &H2)) : •RESTORE
430 THO = 0:FTR = O : FSCT=1 : COMS = ,# W ,f ♦CHRS (&HA0 ) : H1=&H40
440 SCT=256 : SPT=16
450 GOSUB"R/W”
460 1
470 BEP:P:C し S4
480 D$ = USR0(CHR$(0 f &H2)) : 1 RESTORE
490 TR0 = 0:FTR = 0 : FSCT=1 :COMS:"R ..CHKSUH80) : HI:&H4 0
500 SCT=256 : SPT=16
510 GOSUB M H/W tf
520 D$ = USR0(CHR$(11 9 &H1)) : 1 MOTOR OFF
530 END
540 1
550 LABEL ## R/W ff : f GIVE ME TR0 • FTK • FSCT • COMS • H I • SCT , SPT
560 TR=FTR : SABA=FSCT : PLUS=SCTtSPT/256
570 FOR SIDE=0 TO1
580 D$ = USR0(CHR$(11 f &H814SIDEt16)) : f MOTOR ON
590 D$=USR0(CHR$(1 t &H1E f TR f TR0)) : TH0=TR : f SEEK
600 IF HI+PLUS>=&H100 THEN P=(&H1O0-HI)/(SCT/256) ELSE P=SPT
610 IF SABAOl THEN P = P-SABA
620 D$=USR2(COMS4CHR$(SABA f P f 0 f HI)) : SABA:1
630 PRINT ASC(DS) f SABA t P f HEXS(HI)
640 HI=HI+Pt(SCT/256):IF HI>=&H100 THEN RETURN
650 NEXT
660 TR=TR+1 : GOTO570
670 p
680 LABEL"GSMPL"
690 C^S4:INIT
700 F0R TO 10 : X1 = INT(RND(1)t640) : Y1 = INT(RND(1)*200) : C=INT(RND(1)«7)-fl
710 LINE(X f Y)-(X1 f Y1)•XOR , C:X=Xl : Y:Y1
720 NEXT:RETURN
EX
EXX
LD
JR
C.E
WRT1
;BC = DR
WRT2 :
WRT3 :
R し CA
;BACK STAT
LD
(1X4^0) ,A
;STORE
OR
A
CHECK ERROR
JR
NZ f WRT3
ERROR THEN END
INC
L
IX^2=SCTNO
DEC
(IX + 3>
IX-f3=COUNT
JR
El
RET
NZ f WAGAlN
SETFDC
WAIT :
LD
A f L
LD
BC f SCR
OUT
<C) f A
LD
BC f CR
OUT
(C) f H
LD
A f 7
DHC
A
JR
NZ,WAIT
RET
KND
IX+2=SCTNO
CR=STR
o
0
3
o
B
E
7 6 5 B
7 0 3D
8 9 B 8 7D70CD0B9
0 D 41 0DB22D2FC
試験
リスト 9-13 が応用例だが, G-RAM — FD の 機械語 ルーチン, USR 2 の呼び方は,
USR 2 ((1^, } + CHR $ (コマンド, 先頭 セクタ,セクタ 数, アドレス 下位, アドレス
上位))
である0アドレスとはデータの始まる G - RAM のアドレスである。このアドレスは,グラ
フィック全画面のセーブ/ロードなどでは頻繁に変化するものなので, POKE 文を使いた
くなかったのだ。その見返りとして暴走しやすくなっているから,充分に楽しんでいただ
きたい0プログラムでは680行からのサブルーチンででたらめな折れ線を引き,その後フ
ロッビーディスクにセーブ,画面クリア, G - RAM への口ードを行なっている。興味があ
ったので,シークも含めてすべてを機械語で組んでみたところ(載せないよ 一 だ),理論的
限界に達していることが判明した。すなわち,1周分の16セクタを読み書きするには 0 J
秒が必要だから,全画面をセーブ/ロードするにはシーク時間を入れなくても,どうしても
2.4 秒以上かかるのである。大体において,その程度の時間で読めているから,それ以上の
ことをするにはリスト9-10, 9-11 などを使って1トラック当たりの容迸を増やすなどし
なければならない。1セクタ1024バイトのフォーマットならば,5シリンダ (50 K バイ
卜)で済むから,全画面ロード/セーブはシーク時間を入れずに2秒が限界になる(しかも
シークが1回少なくて済む)。 FDC の楽しみはこのようにして深く,広くなっていくのであ
った。
TYPE IV
XI の場合はコマンドの打ち切り機能だけである。
冷し TDMAT あ 3
ここから先では DMA が必要なので, turbo / turboZ ユーザーだけに意味がある。
さて, 2 D , 2 DD のディスクを扱うのならば DMA がなくとも子は育つのだが, 2 HD とな
るとそうはいかない0データの転送速度が2倍になるので, CPU で シャコシャコと データ
を送っていたならば間に合わなくなってしまうのである。そこで DMA を使ったディスク
アクセスへと向かうわけである。ちなみに,リスト 9-4 の DMA を使わずにディスクアク
セスするプログラムで試したところ,やはりしっかりと 「LOST DATA エラー」が起き
てしまった。そのよ一なわけであるから,やはり DMA はただ者ではないのである。
Z は別だが, turbo ユーザーで 2 HD を持っている人はあまりいないであろう。しかしご
安心0 DMA を使ってのディスクアクセスは, 2 HD ばかりではないのである。すなわ
ち,
2 D , 2 DD でもできるのだ。
その場合のメリットは,
1) プログラムが短くなる
2) 恐ろしいことに, オール BASIC で書けてしまう
第9章フロッピーディスク 217
という 2 点である。念のために言っておくと,当たり前のことだが, 2 D , 2 DD では DMA
を使っても使わなくても,ディスクの回転速度は変わらないのであるから,基本的にリー
ド/ライトの速さは変わらない。
ところで CZ -520 F や turboIII , Z の内蔵ドライブなどの 2 D , 2 DD , 2 HD 兼用タイプの
ドライブを使ううえで大事な注意点がある。
それは,それらのドライブは 2 D の書き込みはできるが,書き込みをしたならば他の 2 D
専用のドライブでの読み込みは保証されないということである (2 DD は問題ない)。
具体的に言うと,たとえばスイッチを切り換えて 2 D モードにする。その状態で,ディス
ク(もちろん 2 D のフォー マツ トになっている)に何かを書いたとする。そのディスクをそ
のタイプのドライブで読む分にはなんの問題もないのだが,他の 2 D 専用のドライブ
( X 1 G , turbo , turboll の内蔵ドライブ, CZ -800 F ,801 F ,502 F など)に差し替えたとす
ると,リードエラーが起きる可能性があるのだ。もの好きな私であるから早速試したのだ
が, turbo の内蔵ドライブでは34番トラックあたりまではよかったのだが35番トラック
でリードエラーが起きてしまった。ところがどっこい CZ -800 F ではすんなりと読めてし
まったのである。そのよ一な状況であるから,注意していただきたい。なお,この点は他
機種のドライブにおいても状況は同じだそうである。
なお,知っている人は知っていると思うが, 2 HD ではディスクの回転速度が毎分360回
(= 毎秒6回)であり,2 D , 2 DD では毎分300回 (= 毎秒5回)である。すなわち2 D ,
2 DD , 2 HD 兼用タイプのドライブは,動作モードによって回転速度が自動的に変わるので
ある。
脱あ 3
ここで一言断っておく。今発見したところなのだが, turbo , turbo II などでは ,ノー
マルの 2 D 専用ドライブで(つまり 2 HD を扱えないドライブで)5インチの単密度 (FM
方式)が使えるようなのである(つまり5インチの 2 S というフォーマット)〇私は今まで
2 S も 1 S も見たことがないし,読者もほとんどの方が見たことがないであろう ( Applell は
1 S に近いそうだが,ちょっと違う)。そのよ一なわけで,以後の文中ではこのフォーマット
は無視する。なにせすでに死に絶えてしまったフォーマットであるから,使い道はないの
である。製造元のシャープでも 2 S については何も保証しないだろうと思われる。
本題 T あ 3
XI の5インチ 2 HD の物理フォーマットには XI フォーマットと標準フォーマットの2
種類がある。 XI フォーマットとは全部 MFM で,77シリンダ,2サイド,各サイドには
77トラックあり,1トラックには26セクタあり,セクタの容 M は256バイトの(ああ面倒
臭い)フォーマットである0標準フォーマットとは, IBM フォー マッ ト (8 インチ)と同
じフォーマットで,第0シリンダのサイド0が単密度になっているものである。
218 試験に出る XI
というわけで,ここでは XI フォーマットを基本として話を進める。まずは リスト 9-14
である0これはリスト 9-5 に相当するものである。つまり, FDC の MB 8877/8876 のコマ
ンドをすべて実行できるようにしてある。 BASIC は turbo BASIC ( CZ -8 FB 02) を使って
いただきたい。使い方は四つの変数, TR , OLDTR , SCT , CMD に必要な値を入れて
GOSUB するのである。実行に当たっては,打ち込みミスがあると悲惨なことになるの
で,壊れては困るファイルが入っているディスクは,すべてのドライブから抜いておくこ
と。また一度このプログラムを走らせた後に, LOAD , SAVE を行なうときには,まずは
FILES を実行していただきたい。もしディスク周りのモードがおかしくなっていたな
ら,変なものが表示されるから,そのときはディスクアクセスは すべきではない。 そし
て,素直に IPL をかけて,バグ捜しとなる。 DMA がその筋すると電源を落とさなければ
ならない場合もあるので心得ていただきたい。なお,1020行と1150行に 「 CMD = — 1」と
いう理不尽な式があるが,これはただの縁起ものと考えていただきたい。バッファ用のデ
-夕領域は C 000„ 〜を使っている。リードトラックを実行すると, E 8 B 0„ あたりまで使うこ
とになるので,まだ 4 K バイトほど余裕がある0では1190行から始まるサブルーチンを順
に解説する。
• "SET HD "
2 HD の MFM モードにする。正確には,1200行で 2 HD モードにし,1210行で MFM モ
ードにしている。 2 HD とはいっても , MFM (倍密度)と FM (単密度)の2種類があるのだ。
• "SET LD "
2 D , 2 DD モードにする。
•、、SET FM f/
2 HD の FM モード(単密度)にする0
• '' MOTOR "
ドライブのモーターの ON / OFF , サイドの選択をする。
• '' RESTORE "
第0ト ラックへシークす る(ヘッドを移動する)。
•、、 SEEK "
へッドを移動する。始まりのトラック番号は OLDTR , 行き先のトラック番号は TR で
ぁる。
• '' STEP "
直前に動いた方向に,もう1トラック分シークする。
• ''STEP IN "
内側(トラック番号が増える方向)に1トラック分シークする。
•、'STEP OUT "
外側(トラック番号が減る方向)に1トラック分シークする。
• "READ DATA "
SCT で指定された番号のセクタを C 000 H からに読み出す。
さて,ここで初めて DMA の登場である。 DMA に対するコントロール内容は1700行に
第 9 章 フロッピーディスク 219
あるとおり。すなわち,
83 H = WR 6 で DMA 停止の意味。
7 D „ = WR 0 で動作は転送で,方向はポート A — ポート B を指定。次にポート A の開
始アドレスとブロック長が来る。
FB „, OF „ = FDC のデータレジスタの I / O アドレス。
FF „, 00„ =ブロック長 ( DMA の都合により一1しておく)〇1セクタが256バイトだ
からこうなる。
2 C „ = WR 1 でポート A はアドレスが固定で, I / O であることを指定。
10„ = WR 2 でポート B はアドレスがインクリメント(増加)でメモリであることを指定。
80„ = WR 3 で特に何もしてない。
8 D „ = WR 4 でバイトモードを指定。次にポート B の開始アドレスが来る0
00 H , C 0„= メモリのデータ領域(バッファ)のアドレス0
92„ = WR 5 で CE / WAIT をマルチブレクス,またレディの極性は Low 。
CFh = WR 6 で 口ード コマンド0
87„ = WR 6 で DMA イネーブル0
以上のように DMA を設定してやると, DMA は FDC からのレディ信号を待つ状態にな
る。そこで FDC にリードコマンドを送ってやると,その後 FDC と DMA の間で 勝手に デ
一夕の転送をしてくれる。 DMA はバイトモードであるから,転送する間を縫って CPU が
動作している。データリードが終わったかどうかは, CPU が FDC のステータスレジスタ
を見張って, BUSY でなくなったかで判断する。終わったならば DMA に83„を送って動
作を停止させておく。
• ''WRITE DATA "
SCT で指定された番号のセクタに C 000„ からのデータを書き込む。
DMA に対するコントロール内容は,
83„ = WR 6 で DMA 停止の意味。
79„ = WR 0 で動作は転送で,方向はポート B — ポート A を指定(後でポート A — ポー
卜 B にひっくり返す)。次にポート A の開始アドレスとブロック長が来る。
00 H , C 0„ = データ領域のアドレス0
FF „, 00„ =ブロック長 ( DMA の都合により一1しておく)。1セクタが256バイトだ
からこうなる。
14„ = WR 1 でポート A はアドレスがインクリメント(増加)で,メモリであることを
指定。
28„ = WR 2 でポート B はアドレスが固定で I / O であることを指定。
80„ = WR 3 で特に何もしてない。
8 D H = WR 4 でバイトモードを指定。次にポート B の開始アドレスが来る。
FB „, 0 F „ 二 FDC のデータレジスタの I / O アドレス。
92„; WR 5 で CE / WAIT をマルチプレクス,またレディの極性は Low 。
CF „= WR 6 で,口ードコマンド。これにより 今のところ 2 バイト目の 79„ でソース側
220 试験に出る XI
に指定されているポート B に開始アドレス ( OFFB h ) がロードされる0これを怠ると正
常に動作しない。
05„ = WR 0 でポート A — ポート B に転送方向を指定し直している。
CF „ = WR 6 でもう 一度 口ードコマンド 0
87„ = WR 6 で DMA イネーブル0
以上の設定の後に FDC にデータライトコマンドを送ってやると, DMA と FDC が勝手
に肖き込みをやってくれる。そのほかは "READ DATA " と同じ。
• "READ ID "
ブロック長が6バイトになったこと以外は '' READ DATA " と同じ(リスト中では 一 1
して05„,00„となっている)。
• ''READ TRACK "
ブロック長が 28 B 0 h バイトになったこと以外は ''READ DATA " と同じ0
• "WRITE TRACK "
ブロック長が 28 B 0„ バイトになったこと以外は ''WRITE DATA " と同じ。
• "FORCE INT "
FDC にコマンドを送るだけ。
このよ一にして DMA を使ったディスクアクセスはオール BASIC してしまうのであっ
た。リスト 9-14 では CZ -520 F をドライブ2,3とした場合を考えている。1020行を
GOSUB ''SET LD " にし,1030行などで, 、、 MOTOR " に与えるコマンド ( CMD ) を&
H 81 などにすると内蔵のドライブ1に DMA を使ってアクセスできる。
リスト 9-14 DMA でデイスクアクセス
000
CLEAR
&HC000
010
f TR,OLDTR,SCT
020
030
040
050
•TR=1
: OLDTR=
060
I
070
t
080
t
090
SCT=1
100
SCT=1
110
,
120
9
130
t
140
t
150
160
170
END
180
9
190
LABE し "
SET HD"
CMD = -1
CMD=&H 82
CMD = &H0
: CMD = &H1C
CMD=&H38
CMD=AH58
CMD=&H78
: CMD = AH80
: CMD = &HA0
CMD=&HC0
CMD=&HE0
CMD=&HF0
CMD=&HD0
CMD=-1
CMD=&H2
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB,
GOSUB.
GOSUB.
GOSUB.
GOSUB.
•SET HD”
•MOTOR”
•RESTORE”
•SEEK M
•STEP”
,STEP IN”
•STEP OUT"
READ DATA”
WRITE DATA"
READ ID ff
READ TRACK"
WRITE TRACK
FORCE INT”
SET LD"
MOTOR”
200
210
220
230
240
250
260
270
280
290
300
310
320
DUMMY=INP(&HFFE)
DUMMY=INP(&HFFD)
STAT=0
RETURN
t
LABEL"SET LD"
DUMMY=INP(AHFFF)
DUMMY=INP(&HFFD)
STAT=0
RETURN
9
LABEL"SET FM M
DUMMY=INP(AHFFE)
2HD MODE
MFM MODE
2D/2DD MODE
MFM MODE
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB
GOSUB,
GOSUB
GOSUB_
GOSUB,
GOSUB.
GOSUB 1
GOSUB.
GOSUB •
ER?
ER?
ER?
ER?
ER?
ER?
ER?
ER?
KR?
ER?
ER?
ER?
ER?
ER?
ER?
2HD MODE
第 9 章フロッピーディスク 221
1330
1340
1350
1360
1370
1380
1390
1400
1410
1420
1430
1440
1450
1460
1470
1480
1490
1500
1510
1520
1530
1540
1550
1560
1570
1580
1590
1600
1610
1620
1630
1640
1650
1660
1670
1680
1690
1700
1710
1720
1730
1740
1750
1760
1770
1780
1790
1800
1810
1820
1830
1840
1850
1860
1870
1880
1890
1900
1910
1920
1930
1940
1950
1960
1970
1980
1990
2000
2010
2020
2030
2040
05<
2060
2070
2080
2090
2100
2110
2120
2130
2140
DUMMY=INP(&HFFC) : , FM MODE
STAT=0
RETURN
9
LABEL ,, MOTOR ,f
OUT &HFFC.CMD
IF CMD AND &H80 THEN GOSUB"WNBSY
RETURN
LABEL”RESTORE”
OUT &HFF8 f CMD
GOSUB"WNBSY”
RETURN
9
LABEL M SEEK M
OUT &HFFB f TR
OUT &HFF9 f OLDTR
OUT &HFF8 f CMD
GOSUB"WNBSY"
RETURN
9
LABEL..STEP"
OUT &HFF8 f CMD
GOSUB M WNBSY #f
RETURN
9
LABEL°STEP IN"
OUT &HFF8,CMD
GOSUB°WNBSY #f
RETURN
9
LABEL..STEP OUT"
OUT &HFF8 f CMD
GOSUB f# WNBSY ,f
RETURN
: f DATA REG. ( 目的のシリンダ # 号)
: 1 TRACK REG. < 現在のシリンダ # 号 }
LABEL ,# READ DATA"
DMAS = HEXCHR$( lf 83 7D FB 0F FF 00 2C 10 80 8D 00 C0 92 CF 87
GOSUB”SETDMA"
OUT &HFFA f SCT : 1 SECTOR REG.
OUT &HFF8 f CMD
GOSUB M WNBSY"
GOSUB lf RESETDMA ,f
RETURN
LABEL M WRITE DATA"
DMA$=HEXCHRS(”83 79 00 C0 FF 00
GOSUB..SETDMA”
OUT &HFF8 t CMD
GOSUB..WNBSY"
GOSUB"RESETDMA"
RETURN
14 28 80 8D FB 0F 92 CF 05 CF 87
83 7D FB 0F 05 00 2C 10 80 8D 00 C0 92 CF 87
LABEL ff READ ID"
DMA$ = HEXCHR$( ff
GOSUB"SETDMA. f
OUT &HFF8 f CMD
GOSUB ff WNBSY M
GOSUB ff RESETDMA
RETURN
LABEL lf READ TRACK”
DMA$ = HEXCHR$( tf 83 7D FB 0F AF 28 2C 10 80 8D 00 C0 92 CF 87
GOSUB"SETDMA"
OUT &HFF8 f CMD
GOSUB"WNBSY”
GOSUB ff RESETDMA tf
RETURN
LABEL if WRITE TRACK”
DMAS = HEXCHR$( f# 83 79 00 C0 AF 28
GOSUB"SETDMA”
OUT &HFF8 f CMD
GOSUB”WNBSY"
GOSUB M RESETDMA ,f
RETURN
9
LABEL**FORCE INT"
OUT &HFF8,CMD
STAT=INP(&HFF8)
RETURN
14 28 80 8D FB 0F 92 CF 05 CF 87
試験に出る XI
2150 LABEL"RESETDMA M
2160 DMA$ = HEXCHR$( M 83 M ) : GOSUB f# SETDMA #t
2170 RETURN
2180 1
2190 LABEL"WNBSY"
2200 CT = 0
2210 IF CT>1000 THEN OUT &HFFC.&H3 AND DN : PRINT t# DISK? 11 : STOP
2220 STAT=INP(«cHFF8) : IF STAT AND &H81 THEN CT=CT+l:GOTO 2210
2230 RETURN
2240 1
2250 LABEL M SETDMA ft
2260 FOR 1 =1 TO LEN(DMAS):OUT &H1F80 f ASC(MID$(DMAS f I f 1)) : NEXT
2270 RETURN
2280 1
2290 LABEL f, ER? M
2300 PRINTHEXS(CMD) f HEX$(STAT)
2310 RETURN
SHD 勿物理フォーマットてあ3
DMA を使ったディスク フォーマッ トブログラムであるが,リスト 9-9 を図 9-11 に従っ
て削除/訂正/追加していただきたい(1010〜1170行の削除を忘れずに)。できあがったもの
がリスト 9-8 に相当するディスク フォーマッ トブログラムである。これは turbo BASIC
でも動くようになっている(もちろん CZ -8 FB 01 でも動く)。 RUN するとドライブ番号1
(2 HD ) に入っているディスクに物理 フォーマット をかけるようにしてある。打ち込みミス
があると悲惨なことになるので,壊れては困るファイルが入っているディスクはすべての
ドライブから抜いておくこと。
さらには2000行以降をリスト 9-15 と差し替えると,1セクタの容置が512バイトでセ
図 9-11 「リスト 9-9 J - DMA を使つた 2 HD ディスクフォーマットプログラムへの変更点
クタの数が15個, リスト 9-16 と差し替えると1セクタの容世が1024バイトでセクタの数
が8個のフォー マッ トになる。挙げ句の果てに, リスト 9-17 は FM (単密度)用のフォー
マッ トである。1235行と1445行も いっしょに 付け加えていただきたい。
もちろん少しの訂正で2 D , 2 DD にフォーマットをかけるように変更することも可能で
ある。その点については自由研究である。
リスト 9-15 2 HD 1セクタ512バイトへの変更点
2000 LABEL M GAP1 M
2010 DATA 80.&H4E, 12 f &H00 f 3, &HF6 ,1 f &HFC f 50 f &H4E f 0
2020 LABEL"SECTOR"
2030 DATA 12,0 f 3 f &HF5 f l f &HFE,4 f !
2040 DATA 1,&HF7 , 22,&H4E , 12 , 0 , 3,&HF5,1,&HFB,512,&HE5,1,&HF7,84 , &H4E , 0
2050 LABEL"GAP4" : , ^ "
2060 DATA 400,&H4E,0 : , い!!! !!! !!!
2070 LABEL M TOTAL SECTOR"
2080 DATA 15 : , く -!!!
2090 LABEL M SQUE n
2100 DATA 1 , 2,3,4,5,6,7,8,9 , 10 , 11 , 12 , 13 , 14,15
2110 LABEL M TYPE M
2120 DATA 2 : , く一 !!! 1 SECTOR 512 Byte つうことでん力《な
リスト 9-16 2 HD 1セクタ1024バイトへの変更点
2000 LABEL M GAP1 M
2010 DATA 80.&H4E, 12 f &H00 f 3 f &HF6 ,1 f &HFC f 50 f &H4E f 0
2020 LABEL”SECTOR"
2030 DATA 12 f 0 f 3 f &HF5 f 1 f &HFE f 4 f !
2040 DATA 1,&HF7,22,&H4E , 12,0•3•&HF5•1 , &HFB,1024,&HE5,1 f &HF7 f 116 f &H4E f 0
2050 LABEL"GAP4" : » へ れ
2060 DATA 654 9 &H4E V 0 : , く -!!! !!! !!!
2070 LABEL M TOTAL SECTOR"
2080 DATA 8 : , <-!!!
2090 LABEL M SQUE M
2100 DATA 1 , 2, 3 ,4,5,6,7, 8
2110 LABEL M TYPE M
2120 DATA 3 :’ く -!!! 1 SECTOR 1024 Byte つうことでんがな
リスト 9-17 2 HD 1セクタ128バイトへの変更点
1235 DUMMY=INP(&HFFC) : , F M モート•にする
1445 DUMMY=INP(&HFFD) :, MFM モードにする
2000 LABEL"GAP1"
2010 DATA 40 f &HFE,6 f &H00 f 1 t &HFC f 26, &HFF ,0
2020 LABEL"SECTOR”
2030 DATA 6,&H00,1,&HFE,4,!
2040 DATA 1,&HF7 f 11,&HFF,6 , &H00,1 , &HFB,128 f &HE5 f 1,&HF7 f 27,&HFF f 0
2050 LABEL”GAP4" : 1 " "
2060 DATA 247 f &HFF,0 : , く -!!! !!! !!!
2070 LABEL M TOTAL SECTOR •’
2080 DATA 26 :*<-!!!
2090 LABEL M SQUE M
2100 DATA 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
2110 DATA 17 f 18,19,20,21,22,23,24,25,26
2120 LABEL"TYPE"
2130 DATA 0 : , く一 !!! 1 SECTOR 128 Byte つうことでん :^ な
224 試験に出る XI
以上のフォー マッ ト用のデータの内訳は,例によって参考文献10のお世話になって い
る。
クラフィックす 3<7 VT あ3
DMA の性質としてメモリと I/O は同等に扱えるということである。そこで私の傾向と
性格により,リスト 9-14 にリスト 9-18 を追加変更するとたちまちにして FD — G-RAM
プログラムができてしまうのである。変更点は,ディスクからリードする場合は転送先を
I/O にしたことと,アドレスを G-RAM の始まりの 400 0 H にしたことである。ライトする場
合はよって知るべしである。—と害くともっともらしく聞こえるが,実はそれだけで
は動かない。というのは, BASIC が G-RAM のバンク〇, 1 を勝手に切り換えるからなの
だ。実に残念なことよ。
リスト 9-18 G-RAM アクセス用変更点_
1700 DMA$=HEXCHR$("83 7D FB 0F FF 00 2C 18 80 8D M )
17 05 DMA$ = DMA$ + MKI$(&H4000 >+HEXCHR$("92 CF 87">
1790 DMA$ = HEXCHR$( M 83 79••)+MKI$ <&H4000 >
1795 DMA$ = DMAS + HEXCHR$rFF 00 1C 28 80 8D FB OF 92 CF 05 CF 87")
V フト的なフォーマットてあ 3
2 HD ,2 DD のディスクでは容量が違うのであるから, BASIC によるファイル管理も少々
違っている。詳しくは turbo の USER’S MANUAL の187ぺージあたりに害いてある
が,大事な点は 2 HD でも1クラスタは 4 K バイトのままで,これは1トラック(片面)の容
M ではないということである。 2 D のなごりを引きずっているわけだ。さらにはクラスタ番
号である。 2 DD , 2 HD ではクラスタ数がそれぞれ 12 8以上あるが, FAT 内では 80„〜8 F „
はチェーンの終わりを示すものであったから,この番号のクラスタはあってはいけないこ
とになっている。そこで BASIC でどのようにごまかしているかというと,
1) 実はクラスタ番号は2バイトの値 (16 進数で4桁)を持つ
2) そして,下2桁が80„〜 FF „ •の部分は番号を飛ばす
となっているのである。要するに, 2 DD ,2 HD ( 8インチやハードディスクも)では FAT
の位置(レコード番号)やディレクトリの位置が違うということである。
さらにヴラフィックす3必 T あ3
リスト 9-19 である。このブログラムはリスト 9-14 +リスト 9-16 で 作った, 1 セクタが
1024 バイトのフ ォーマッ トのディスクを 画像用に してしまう ものである。具体的に 言う
と, 1 トラック(片面)に 8 セクタ あり,1 シリング (裏表で計2 トラック)が 16 K バイ
第9章 フロッピーディスク 225
卜であることから,3シリンダに 48 K バイト分のグラフィックデータを書き込んでしまう
のである。ディスクアクセスにはマルチセクタを使っている 0 FDC の説明の最初の所でも
書いたが,マルチセクタを使うと FDC は 「RECORD NOT FOUND 」 でエラーを起こす
まで BUSY のままである。そこでここでは DMA の「エンド•オブ•ブロックで割り込み」
の機能を使っている。これにより FDC が第9セクタ(ここでは存在しない)を捜してエラ
一を起こすのを待たずに済むようになっている。最初にある MEM $ は, FDC のステータス
レジスタを読み出すルーチン+割り込み処理ルーチンである0 「FDC のステータスをチェ
ックするなら BASIC の INP 関数を使えばよい」と思うだろうが,実はそこには恐ろしい
ワナが隠されている。なんと,私の調べたところによると, INP 関数を使うと BASIC
は,
勝手に G - RAM の入カページ(パンク〇, 1) をひっくり返してしまう
のだ。よって CALL 命令で呼び出した 機械語 プログラムによって FDC のステータスをチ
ェックしなければならないのだ0もっともこの部分は徹底的に探ったわけではないから,
いまいち確信はないのだが。 ま,とに?^ く そのようなわけなのである。
リスト 9-19 48 K G-RAM 口ード/セーブブログラム
100 CLEAR &HEF00
110 MEM$(&HEF00 t 16)=HEXCHR$( ft 01 F8 0F ED 78 32 26 EF C9 F3 F5 C5 0180 IF 3E )
120 MEM$(&HEF10,16)=HEXCHR$( ,# AF ED 79 3E 8B ED 79 3E AB ED 79 3E 0132 25 EF ,# )
130 NEM$(&HEF20 t 7) =HEXCHR$ ( M C1 FI FB ED 4D 00 0O #, )
140 INIT
150 DN=1
160 DUMMY=INP(&HFFE) : f 2HD(1.6) MODE
170 MEM$(&HF814 t 2)=MKI$(&HEF09) : f OLD VALUE = &H81C3
180 1
190 GOSUB..RESTORE" :OLDTR = 0
200 FOR TTR=0 TO 72 STEP 3
210 CLS4
220 SYMBOL(32 t 0) f STR$(TTR) f 20 t 10 f 7 f 0 f PSET
230 GOSUB"WRITE"
240 NEXT
250 1
260 GOSUB tf RESTORE tf : OLDTR=0
270 FOR TTR=0 TO 72 STEP 3
280 CLS4
290 GOSUB..READ"
300 NEXT
310 1
320 OUT &HFFC,&H3 AND DN
330 DUMMY=INP(&HFFF) : 1 2D f 2DD(0•5M f 1M) MODE
340 MEM$(&HF814 f 2)=MKI$(&H81C3)
350 END
360 1
370 LABEL M READ M
380 CCC=&H 90
390 DD1$ = HEXCHR$( "83 7D FB 0F FF IF 2C 18 9D ff )
400 DD2$ = HEXCHR$( ft 3210 92 A0 CF 8B 87" >
410 GOSUB lf EXEC ff
420 RETURN
430 1
440 LABEL f, WRITE tf
450 CCC=&HB0
460 DDl$ = HBXCHR$( ff 83 79 ff )
470 DD2$ = HEXCHRS( ff FF IF 1C 28 9D FB 0F 3210 92 CF 05 A0 CF 87" >
480 GOSUB”EXEC"
490 RETURN
500 1
510 LABEL ft EXEC ff
520 GAD=AH4000
530 FOR TR=TTR TO TTR+2
540 GOSUB"SEEK” : OLDTR=TR
226 試験に出る XI
550 FOR SIDE=0 TO1
560 DMAS = DD 1 $ ♦MKI $ (GAD ) -fDD2S
570 GOSUB M SETDMA ff
580 OUT &HFFC f &H 80 OR DN OR &H10 拿 SIDE:GOSUB ”WNBSY” : , MOTOR ON
590 OUT &HFFA f 1 : 1 SECTOR #
600 POKE &HEF25 f 0 : 1 CLEAR FLAG
610 OUT &HFF8 f CCC : 1 COMMAND
620 CALL &HEF00
630 IF (PEEK(&HEF26) AND 1)=0 THEN 660
640 IF PEEK(&HEF25) THEN 660
650 GOTO 620
660 PRINT PEEK(&HEF25) t PEEK (&HEF26 ) f INPUHFF8)
670 OUT &HFF8 t AHD0
680 GAD=GAD^&H2000
690 NEXT
700 NEXT
710 DMA$ = HEXCHR$( M C3 C3 C3 C3 C3 C3 83 80 M ) : GOSUB #f SETDMA tf
720 RETURN
730 1
740 LABEL tf WNBSY M
750 CT=0
760 IF CT> 1000 THEN OUT &HFFC f &H2 : PRINT M DISK? M :STOP
770 IF INP(&HFF8) AND &H81 THEN CT=CT+l:GOTO 760
780 RETURN
790 f
800 LABEL ff SETDMA fl
810 FORI=1TOLEN(DMAS) : OUT &H1F80 f ASC(MIDS(DMASiI,1)) : NEXT
820 RETURN
830 f
840 LABEL ff SEEK if
850 OUT &HFFB f TR :’ デ-タレジスタ
860 OUT &HFF9 f OLDTR ソトラックレジスタ
870 OUT &HFF8 t &H10 :•シークコマンド
880 GOSUB..WNBSY"
890 RETURN
900 1
910 LABEL M RESTORE M
920 OUT &HFFC t &H 80 OR DN:GOSUB •• WNBSY” :• MOTOR ON
930 OUT &HFF8 f &H0 : GOSUB "WNBSY ••ノ HOME
940 RETURN
それでリスト 9-19 でやっていることだが,中心は370行以降の、、 READ " と、、 WRITE "
である。それぞれのルーチンは変数 TTR (Top Track ) から始まる3シリンダと 48 K バ
イトの G - RAM の間でデータの読み書きを行なう。ブログラム全体では,最初は SYM
BOL 文を使って G - RAM に丁 TR の値をでかでかと書き,それを次々 と ディスクに書き
込み,次には,次々に読み出して表示している。これは実行させてみれば一目瞭然であろ
う。そこで110〜130行の MEM $〜 による機械語ブログラムを簡単に説明しておく。 アセ
ンブルリストは,リスト 9-20 である o EF 00„ 〜 EF 08 H は単に FDC のステータスを読み出し
て EF 26 j 地に格納しているだけである。大事なのは EF 09 H 〜 で,これは「エンド•オブ.
ブロック」後の DMA の再初期化と「フラグ立て」 ( EF 25„ 番地)を行なっている。このフ
ラグが立つたなら, DMA が 8 K バイトの転送を終えたわけだから, FDC の空しい第9 セ
クタ捜しをフォースインタラブトで打ち切ってやるわけである。
リスト 9-20 「リスト9-19」の機械焐部分
第9章 フロッピーディスク 227
EF08
EF09
EF0A
EF0B
EF0C
EF0F
EF11
EF13
EF15
EF17
EF19
EF1B
EF1D
EF20
EF21
EF22
EF23
EF25
EF26
RET
DMAINT : DI
PUSH
AF
PUSH
BC
LD
BC,DMA
LD
A f 0AFH
; WR6:DISABLE
INT.
OUT
(C) ,A
LD
A f 08BH
; WR6 : REINIT.
STAT
OUT
(C) ,A
LD
A,0ABH
; WR6:ENABLE
INT.
OUT
(C) f A
LD
LD
A,1
(INTF),A
;SET FLAG
POP
BC
POP
El
RETI
AF
INTF : DS 1
STAT : DS 1
* END
以上が DMA でディスクを使ってみた例である。残念ながら8インチゃハードディスク
などは手付かずとなってしまったが,さっさと次の章に行ってしまうのであった。
0
8
5
2
FF9B9B91F
1A787A70E
D
4
9 3551EDE
c F F C 0 3 E 3
DEDE211BD
E3E33CFFE
228 試験に出る XI
PSG は基本である
第 10 章
PSG は基本 T ある
この章では PSG をやるのである。 PSG というのは , Programmable Sound Genera ¬
tor , すなわち「ブログラム可能な音声発生機」なのである。ブログラム可能とはいっても
別にたいしたことはないからそのつもりで。
X 1で使われている PSG は A Y -3-8910 という,もう古典と言ってもよい LSI である。た
だし turboZ などでは,それとコンパチな YAMAHA の YM 2149 も使われている(ちなみ
に YM 2149 は 「 SSG 」 と呼ばれている。このことから逆に AY -3-8910 を SSG と呼んだり
もする)。
で,この石を簡単に紹介すると,
1) 音 M 調節付きで3重和音が使える。
2) ノイズ(雑音)を使える。
3) エンべ ローブと呼ばれる機能により,指定した周期,形状 (8 パターン)で音童を
変化させることができる。
4) 2ポートの8ビットパラレルポートが使える。 XI ではこれをジョイステイックに使
っている。
などとなる。
AY -3-8910 から 4) の機能を取り去ってピン数を減らしたものは型番が AY -3-8913 と
呼ばれ, MZ - 5500/6500で使われている。 FM -7 では8910, 8913が混在しているそうであ
る。どっちにしても, FM -7 ではパラレルポートを使ってジョイステイックをサボートして
いないから同じことである。
AY -3-8910 の使い方は簡単で,基本的には16個あるレジスタにそれなりのデータを 書
き込んでやったり,もしくは読み出したりすればよい。この点については第1章の CRTC
と似ている。そこで早速 PSG のレジスタ表が 表 10-1 である。
最初に言っておくが, R 0 と Rm R 2 と R 3 , R 4 と R 5 は別々に見ずに「12ビットの値を下8
ビットと上4ビットに分けた」と見るべきである。これは R u と Ri 2 でも同じで,こちらの
方は16ビットの値を上下8ビットずつに分けたものとみなすことができる。この点を注意
しつつ,順に解説する。
® R 0f R , (チヤンネル A トーン 周波数)
R , を上4ビット, R 0 を下8ビットとして作る12ビットの整数を A f とする。 A f は0
〜4095である。すなわち,
Af ― Ro *+■ Rj x 256 . 式1
この A f とチャンネル A から出る音の周波数の関係は,音の周波数を fa ( Hz ) とすると,
《一 2 X 10 6 _ 125000 一
••••••
230 試験に出る XI
となっている。 式 2で 「2 X 10 6 」 と「16」という数値がいきなり出てくるが, 2 X 10 6 とい
うのは, LSI に供給されているクロックの周波数 (2 MHz ) である。だからハードウェア
が異なれば,この部分の値は変わってくる 。 M (メガ)というのは10 6 =1000000の単位
なのだ,念のため。次に出てくる16は, AY -3-8910 を設計した人が勝手に決めた数値
である(と思う)。なお, 式 2より Af の値が大きいほど周波数の小さい音(低い音)が
出ることが分かる。要するに逆比例なのだ。
式 1, 2より「周波数 f ( Hz ) の音を出したいときに,どういう数値を Ro , 心に書き込
めばよいか」を計算できる。
まず, 式 2から,
A _ 125000
At 一
が分かる。ただし A f は整数じゃないとまずいので,小数点第1位で四捨五入するのがよい
だろう。そこで,本当は,
A ,= INT ( 12 ミ 00 + 0.5)
となる。次に A f から R 0 , 心を計算するわけだが,これは簡単に,
Ro=Af mod 256
r *= int ( 4 )
第 10 章 PSG 231
となる。めでたしめでたし。ただし今のうちに言っておくが, R 0 , K だけをセットしても
音は出てこない。注意するように。なお,やってみると分かるが, A f を0にした場合,式
の上では周波数が無限大の音が出ることになる。自然界では当然そんなことはあり得ない
ので, A f = 0の場合は考える必要はない。また,音質を良くするために も 電気回路で
は,あまり高い周波数(成分)の音は増幅されないのが普通だから, そもそもスピーカー
から出ていないはずである。
さてさて,音の高さについて書いてきたのであるが,周波数ばかりで説明していても始
まらない。実用的にはドレミの音階が必要である。そこで 表 10-2 が,え一とえ一と,「1939
年5月ロンドンにおける国際会議で規定された音階表」である。これは(■理科年表 J に載
つていたものである。
表 10-2 国際基準ィ == 440Hz に 基づく十二平均律音階 (単位は Hz)
— ■ ■ , _ 塵— -- — _
1 ■- !
c 2
C ,
卜 ■■ 1
厂
C
c
- (
c 1
c 2
c :,
c *
C 5
: C
16.352
32.703
65.406
130.81
261.63
523.25
1046.5
2093.0
+ ■ ■ J
4186.0
C 2
17.324
34.648
69.296
138.59
277.18
554.37
1108.7
2217.5
4434.9
D
18.354
36.708
73.416
146.83
293.66
587.33
1174.7
2349.3
4698.6
D 5 ,
19.445
38.891
77.782
155.56
311.13
622.25 |
1244.5
2489.0
4978.0
, E
20.602
41.203
82.407
164.81
329.63
659.26
1318.5
2637.0
5274.0
1
21.827
43.654
87.307
174.61
349.23
698.46
1396.9
2793.8
5587.7
F 5
23.125
46.249
92.499
185.00
369.99
739.99
1480.0
2960.0
5919.9
| G
24.500
48.999
97.999
196.00
392.00
783.99
1568.0
3136.0
6271.9
; G 二
25.957
51.913
103.83
207.65
415.30
830.61
1661.2
3322.4
6644.9
A
27.500
55.000
110.00
220.00
1440.00
880.00
1760.0
3520.0
7040.0
1 A 3
29.135
58.270
116.54
233.08
466.16
932.33
1864.7
3729.3
7458.6
B ,
l J
30.868
61.735
、• 1
123.47
246.94
493.88
987.77
1975.5
3951.1
7902.1
(1979年度版理科年表より)
この表には厳格な規則性がある。中央に四角で囲んだ数字があるが,これが a 1 :; と呼
ばれる音で,何がなんでもここは 440 Hz なのである。これはラの音である。 XI で出すの
なら,
PLAY 、 '04A"
で出てくる。この音を基準として,半音上げた音 (;? A ) の周波数は,440に* 2 /^ = 2ム=
1.05946 …… (2 の12乗根)を掛けたもの,逆に半音下げた音 (# G ) は440を 12 で割
ったものである。同じように 12 で掛けたり割ったりすると,そのたびに半音上がったり
下がったりする。1オクターブは半音が12個分だから,1オクターブ上の音は,ちょうど
周波数が2倍になるの12乗は2なのだ) 0 逆に1オクターブ下の音は,周波数がち
ょうど2分の1である。表 10- 2を見て納得していただきたい。なお,なぜこのように決め
られているのか不思議に思う人もいるだろうが,それは人間の聴覚 システム がそうなって
いるからなのである。それ以上のことは私の知ったことではない。
では, AY-3-8910 で音階表どおりの周波数の音を出すにはどうすればよいかという問題
に移る。真面目に計算してもよいのだが,私は turbo BASIC の MUSIC@ 命令を使ったの
である。 MUSIC 命令だと,音が出て いる 間はずっと待たされてしまう が, MUSIC@ 命令
232 試験に出る XI
ならば待たされることなく次の命令を実行してくれる。だからそのときに PSG の R 。 と
R , を読み出せばよい。なお,それじゃ MUSIC @ 命令はいつ音を止めるのかというと,タイ
マ割り込みを使っているのである。だから心配せずとも,時期が来れば止まってくれる。
表 10-3 が R 0 と R ! の値を表にしたものである。16進数で, 「 R 0 + RJ の形式でできてい
る。四角で囲んであるところが440 Hz に対応する所である。とはいっても,本当に正確に
440 Hz を出せるわけではない。なにせ R 0 , 心は整数に限られるのである。これはほかの音
階でも言えることで,特に高い音になるほどずれは大きくなる。まあ,こういうものだと
思うしかないのである。なお,1オクターブ上げる=周波数を2倍する = A f を半分にす
る,であることに注意。
表 10-3 各音階に対するレジスタの値 (「Roj + rRu の形式)
C
01 EF+0E
02 77^07
03 BB+03
04 DD+01
05 BEf00
06 77^00
07 3B+00
08 1D+0O
#C
17 + 0E
0Bf07
85403
C2 + 01
E 1400
70 + 00
38 + 00
1 C ♦⑽
D
4D + 0D
A6 + 06
53f03
A9 + 01
D4f00
6Af00
35^00
lAf00
ID
8E + 0C
47 + 06
23 + 03
91+01
C8f00
64 + 00
32^00
19 + 00
E
DA + 0B
ED + 05
F 6 + 02
7Bf01
BDf00
5Ef00
2Pf00
17 + 00
F
2F+0B
97 + 05
CB + 02
65 + 01
B2f00
59^00
2C^00
16.00
#F
8P + 0A
47 + 05
A3i02
51+01
A8i00
54^00
2AfC0
15 + 00
G
F7 + 09
FBi04
7D+02
3E + 01
9F + 00
4Ff00
27^00
13f00
#G
68 + 09
B4f04
5Af02
2D + G1
96 + 00
4Bt00
25f00
12 + 00
EU08
70^04
38402
lvc»oil
8 B ^ O 0
47f00
23 + 00
1U00
#A
62 + 08
3U04
18t02
0 C + 01
86^00
43 + 00
21f00
10t00
B
E9 + 07
F4 + 03
FA + 01
FD + 00
7Ef00
3Ff00
1P + 00
0Ff00
② r 2 , r 3 (チャンネル b トーン周波数)
③ Ru R s (チャンネル C トーン周波数)
②,③はチャンネル A が B , C になっただけで,それ以外はまったく同じである。
④ R 6 (ノイズ周波数)
AY -3-8910 には前述したようにノイズを出す機能がある。といっても別にノイズ専門の
チャンネルがあるわけではなく,チャンネル A 〜 C のうちから割り当てるのである。割り
当て方については⑤で説明する。
ノイズとはどんなときに使うのかといえば,波の音とか爆発音などの効果音ということ
になるだろう。心はそのノイズの周波数を決めるものである。だが,ノイズというの
は,一定の幅の周波数帯の音を含んでいる音のことだから,大体の範囲を決めるというこ
とである。具体的には,周波数が高ければ「シャー J , 低ければ「ザー」という感じの音に
なる。心とノイズの高さは,例によって逆比例の関係になる。つまり, R 6 の値が小さいほ
どノイズの音は高くなる。
(D r 7 (ミキサー, I / O コントロール)
この部分はフラグの集まりと考えるのが手っ取り早い。まず, d 0 〜 d 5 はチャンネル
A , B , C から何を出すのかの指定である。チャンネル A を指定するのは D 3 と D 0 であ
る0 図 10-1 に D 3 と D 0 の値 (1/0) とチャンネル A からの出力の関係を示す。
図 10-1 はほかのチャンネルにとっても同じことが言える。1で OFF , 0で ON と変態
的に負論理になっていることに注意。
D e , D 7 は二つある I / O ポートを入力に使うか出力に使うかの指定である。もちろん 二つ
とも別々に指定することができる。0で入力に指定,1で出力に指定である。 XI では通常
は二つともジョイステイツクからの入力になっているから,ともに0である。なお,実際
第10章 PSG 233
図 10-1 ノイズ/トーン指定ビット
(チヤンネル A の場合)
d 3
Do
チャンネル A 出力
0
〇 1
ノイズ+トーン
0
1
ノイズ
1 1
0
トーン
1
1 1
なし
のジョイスティックポートのデータの受け渡しは R u , R 15 を使う。
⑧ R 8 , R 9, Rio (チャンネル A 〜 C 音量,エンべ口ーブ指定)
R 8 , R 9 , R 10 のそれぞれ下 4 ビットの D 3 〜 Do は音 M を指定する。 4 ビット だから 0 (最
小)〜 15( 最大)までの 16 段階である0ただし D 4 が 1 ならば,その チャンネルはエンべ 口
ープモードになり, D 3 〜 D 0 の値は無視される。この場合の音鐘:は, R u , R 12 , R 13 の指定す
る エンべ ローブ 周期と, エンべ ローブ パターンに 支配される。
® Ru . R12 (エンべローブ周期設定)
これは,次で指定するエンべローブのパターンの周期を設定するものである0エンべ口
ープというのは, 図 10-2 にあるように 8 種のパターンがある。エンべローブ周期は図中の
t e の長さだと思えばよい。
A e = R u +R 12 X256
とすると,
. 256 x A e
te_ 2xl0 5
で計算できる。
エンべ ローブというのは音量を自動的に変えるもので,たとえば r 1秒間だけ音を出し
て,その後は出さない」などということを, PSG が勝手にやってくれる機能である〇図 10
-2 の エンべ ローブパターンを見れば分かるように,音: a アップ/ダウンを延々と繰り返す
パターンもある。
図 10-2 エンベロープのパターン
Rl3 の 値
エンベロープパターン
| -j
a
8
KNNNNNX
b
0,1, 2, 3, 9
N
c
10
d
11
\
e
12
\AAAAAA/
1
f
13
1 <
g
14
h
4, 5, 6, 7,15
■.
234 試験に出る XI
⑧ r 13 (エンべローブパターン指定)
図 10-2 に示すエンべローブパターンのうち,どれを使うかを指定するものである。パタ
ーン b , h は複数の R 13 の値に対応しているが, 「 R 13 には8〜15の値だけを設定するもの
だ」と思っていればよいのだ。
(D Rui Rl 5 ( I / O ポート入出力)
前にも書いたように, XI ではジョイスティックポートの入出力に使われている。 R 14 が
ジョイスティック1, R 1 S がジョイスティック2である。 図 10-3 参照。
図 10-3 ジョイスティックのデータの意味 ( R u , R 15 )
6
4 3 2
0 =向こうに倒した
〇=手前に倒した
0=左に倒した
0=右に倒した
未使用
0 =トリガー1を押した
0 =トリガー2を押した
未使用
⑱最後に PSG へのアクセス法である。
まず,レジスタ番号を指定する0つまり,
OUT & H 1 COO , レジスタ番号 (0 〜 15)
の後に,
OUT & H 1 BOO , データ
で,データを書き込める。逆にデータを読み出すなら,
〜 = INP (& H 1 B 00)
となる。
以上で基礎編の説明を終えたわけである。そして,ここでサンブルブログラムが発動す
るのだ。
サムブルな访 T あ3
リスト 10-1 :ドミソ
表 10-2 を使えば一発で分かるはずである。チャンネル A , B , C にそれぞれドミソを割
り当て, R 7 で三つともトーンのみを指定。後は音量を三つとも15にしておしまいであ
る。
リスト 10-1 ドミソ
100 MUSIC ”R0"
110 SOUND 0,&HDD
120 SOUND 1,&H1
130 SOUND 2,&H7B
第 10 章 PSG 235
140 SOUND 3
150 SOUND 4
160 SOUND 5
170 SOUND 7
180 SOUND 8
190 SOUND 9
&H1 : , ミ
&H3E
&H1 : , ソ
&B111000
15
15
200 SOUND 10,15
さて,このブログラムが実にうっとうしいと思うわけである。そこで リスト 10-2 であ
る0まず,サブルーチン、' QUIET " は PSG を黙らせるサブルーチン, '' XSOUND " は PSG
のレジスタに指定されたデータを次々と設定するサブルーチンである 0 、' QUIET " を使うに
は,ただ呼ぶだけでよい。'' XSOUND " は少々複雑である。使うには,まず DATA 文を用
意する。約束ごとは次の五つである。
1) 最初は,レジスタ番号をデータとする。たとえば r 1」ならば心から設定を始める
ことになる。
2) レジスタに設定したいデータは,〇〜255まで, & H 〜, & B 〜などもよい0
3) 設定したくないレジスタに対応するデータは 「 SJ とする。つまり匕と R 6 だけを0
にして, R 5 をそのままにしておきたければ,
DATA 4,0, S , 0,……
とすればよい。
4) DATA 文の最後は 「 EOD」(End Of Data ) とする。
5) GOSUB 、、 XSOUND " の直前に,
RESTORE (データ文の行番号,もしくはラベル)
を実行しておく。
てなとこである。もっとも,それは XI ユーザーに限ってのことで, turbo ではサウンド
文が拡張されていて, " XSOUND " に相当することがそのまま SOUN D 文で実行できるか
ら,きっと,むっとしているはずである。人生とはそんなものである0ところで,リスト
10-2 で行番号がいきなり1000に飛んでいることからも分かるように,これらのサブルー
チンはほかのリストでも流用される運命にある0心得ておいていただきたい0
リスト 10-2 PSG 用サブルーチン
100 GOSUB°QUIET M
110 RESTORE 120:GOSUB”XSOUND"
120 DATA 0 f &HDD f &H01 f &H7B f &H01H3E f &H01 f S f &B111 000 f 15 f 15 f 15 f EOD
130 PAUSE 10
140 GOSUB"QUIET"
150 END
160 1
1000 LABEL"QUIET"
1010 SOUND 8,0:SOUND 9,0:SOUND 10,0
1020 RETURN
1030 1
1040 LABEL"XSOUND"
1050 READ C
1060 READ AS : IF A$="EOD”THEN RETURN
1070 IF A$="S" THEN GOTO1090
1080 SOUND C,VAL(A$)
1090 C=C+1 : GOTO1060
236 試験に出る XI
リス ト 10-3 :銃声
エンベロープパターンは b を使っている。エンベロープ周期は Ru = 0, R 12 = 20 だか
ら,
. 256x(20x256+0) . 认、
te = --;〇.66(秒)
となる。つまり,最初はボリューム最大で, 0.66 秒の間に 0 まで減少するのである。 3 チ
ャンネルともノイズモードにしてある 〇 130 行を見ても分かるように,何かキーを押すと音
が出る。押し続けると,機関銃となるわけである。
リスト 10-3 銃声
100
GOSUB"QUIET"
110
RESTORE 120 : GOSUB ,f XSOUND ft
120
DATA 6 t 20,&B 000111,16,16, 16 f 0.20•9.EOD
130
IF INKEY$(0) = ff 11
THEN 130 ELSE 110
140
END
150
f
1000
LABEL M QUIET M
1010
SOUND 8,0:SOUND
9,0:SOUND 10,0
1020
RETURN
1030
>
1040
LABEL"XSOUND"
1050
READ C
1060
READ A$:IF A$="
EOD"THEN RETURN
1070
IF A$="S" THEN
GOTO1090
1080
SOUND C f VAL(A$)
1090
C=C+1:GOTO1060
リスト 10-4 : UFO
エンべローブ パターンは g で,3チャンネルともトーン。この手の音を作るのは楽なの
である。
リスト 10-4 UFO
100 GOSUB M QUIET M
110 RESTORE 120:GOSUB"XSOUND”
120 DATA 0, 100 , 0 , 102,0 , 200 , 0 , S,&B111000,16, 16,16,10 , 5, 14,EOD
130 PAUSE 50
140 GOSUB..QUIET"
150 END
160 #
1000 LABEL M QUIET M
1010 SOUND 8,0:SOUND 9 f 0:SOUND 10,0
1020 RETURN
1030 *
1040 LABEL"XSOUND"
1050 READ C
1060 READ A$:IF A$="EOD"THEN RETURN
1070 IF A$="S" THEN GOTO1090
1080 SOUND C f VAL(A$)
1090 C=C+1 : GOTO1060
リスト 10-5 : SL とヘリコプター
RUN すると,最初に SL の音を出す。次にヘリコブターの音である。ヘリコブターの方
は,チャンネル B がノイズだけである。そのつもりになって聞くと,そう聞こえるものな
第10章 PSG 237
のである。
リスト 10-5 SL とヘリコプター
100 GOSUB"QUIET"
110 RESTORE 120:GOSUB”XSOUND"
120 DATA 6,10, &B11 0111,16 ,0,0,0,6,12,EOD
130 PAUSE 50
140 RESTORE 150 : GOSUB M XSOUND M
150 DATA 0,0, 5 , 0, 0,0,0,5,&B1 00110,16 ,16, 0 , 0,1 , 10, EOD
160 PAUSE 50
170 GOSUB"QUIET"
180 END
190 1
1000 LABEL M QUIET M
1010 SOUND 8,0:SOUND 9 f 0:SOUND 10,0
1020 RETURN
1030 1
1040 LABEL M XSOUND M
1050 READ C
1060 READ A$:IF A$= M EOD M THEN RETURN
1070 IF A$="S" THEN GOTO1090
1080 SOUND C,VAL(A$>
1090 C=C+1 : GOTO1060
リスト 10-6 :波の音
これはよく見かけるサンブルであるが,リスト 10-7 のように,ランダムにエンべローブ
周期を変えてやると本物に近くなる。時間かせぎの PAUSE 文が140行にあるが,別にエ
ンべロープ周期にセツトする値と関係あるわけではない。何をしても音がずたずたになる
わけではないから,適当でよいのだ。
リスト 10-6 波の音
100
GOSUB M QUIET M
110
RESTORE 120:GOSUB"
XSOUND"
120
DATA 6,25,&B110111
,16•0,0 .0 , 99, 14•EOD
130
END
140
9
1000
LABEL"QUIET"
1010
SOUND 8,0:SOUND 9
,0:SOUND 10,0
1020
RETURN
1030
#
1040
LABEL"XSOUND"
1050
READ C
1060
READ A$:IF A $ = 11 EOD 11 TH KN # RETURN
1070
IF A$ = fl S fl THEN GOTO1090
1080
SOUND C f VAL(A$)
1090
C=C+1 : GOTO1060
リスト 10-7 ランダムな波の音
100
GOSUB M QUIBT M
110
RESTORE 120:GOSUB"
XSOUND"
120
DATA 6 f 25,&B110111
f 16.0,0,0.99.14.EOD
130
T=40+INT(RND<1)*60) : PRINTT
140
SOUND 12,t:PAUSE T : GOTO130
150
9
1000
LABEL"QUIET"
1010
SOUND 8,0:SOUND 9
,0 : SOUND 10,0
1020
RETURN
238 试験に出る XI
1030 1
1040 LABEL"XSOUND"
1050 READ C
1060 READ A$:IF A$="EOD"THEN RETURN
1070 IF A$="S" THEN GOTO1090
1080 SOUND C f VAL(A$)
1090 C=C+1 : GOTO1060
以上でサンブルの紹介は終わるが,ここまで見てきて,疑問を持った人もいるはずであ
る。それは何かというならば,エンべローブのパターンはいつ始まるかということであ
る0 R 13 (エンベロープパターン)に値をセットしたときからなのか? それとも, R 8 〜 R 10
の D s を1にセットした瞬間からなのか? ということである。すなわち,エンべローブを
発動するトリガー(引金)は何なのかである。
答えは R 13 である。ここに値を書き込まれた瞬間から,エンベロープパターンに従って音
が出る0これに対して R m R 12 のエンべローブ周期は単なるカウンタの周期ぐらいの
意味しかない0だからリスト 10-7 のランダムな波の音は,それらしく聞こえたのである。
というところで PSG は終わりである。最近は FM 音源が花盛りであるが, PSG も使い
方によっては非常に強力なので,きちんと押さえておいて欲しいのであった。
第10章 PSG 239
FM 音源
FM 音源ナ八卜厶ジーク
■第 11 章
riFM 音源ナ/\トムジーク
この章では FM 音源についてやってしまうのである。となれば目的は MML である。
で, MML であるが, turbo では NEW turbo BASIC により手軽に FM 音源を楽しめるよ
うになった。しかし XI ではそうはいかない。てなわけで,ここでサボートするしだいであ
る。ちなみに Oh ! MZ の連載時にはあちこちにバグが入ったりしたが,それらをすべて直
してある(はずである)。
さて, XI の FM 音源ボードといえば CZ -8 BS 1 なのであるが,このボードの主役は
YM 2151, 別名 OPM と呼ばれる LSI なのである。それに対して他の大概のバソコンに使わ
れている FM 音源の LSI は YM 2203 ( OPN ) なのである。この両者の違いはというと,
• OPM は FM 音源を8チャンネル持っており,それぞれのチャンネルごとに左右(もし
くは両方)出力を選択できる。また LFO 機能が付いている。
• OPN は FM 音源を3チャンネルと, SSG 音源を3チャンネル ( AY -3-8910 と同じ機
能)持っている0出力はモノラルのみ0 LFO 機能は付いていないのでタイマ割り込みを使
いソフトウェアでコントロールする必要がある0
ということになる。要するに OPN の方には肝心の FM 音源が,
3チヤンネルしか
付いていないのである。それに対して OPM には,
8チヤンネルも
付いているのである。これがどういうことかというと,同時に演奏できる楽器の数が3対
8なのである。そしてこれは数だけの問題にとどまらず,音の厚みに影骋するのである。
で, OPM と OPN の使い方(データ)の互換性であるが,基本的に両者には互換性があ
る。ただしエンベロープのタイミングなどが違い,一部に移植できないものもあるらし
い。といっても VIP に付属の200音色を見ても分かるように, 0 PN から移植できないもの
があったとしても,別に不都合があるわけではない。
ちなみに,この FM 音源ボードであるが, I / O アドレスをずらして何枚でもスロットに
させるようにしたら非常にその筋だったと思ったのであるが,残念ながらそうはなってい
ないようである。
というところで, OPM の具体的な説明に入るのであった。
OPMT ぁ3
図 11-1 が OPM の I / O アドレスである。テンポの制御用に Z 80 CTC が付いている
が, turbo および turboZ で動かす場合はこのボード上の CTC ではなく,本体内蔵の CTC
(アドレスは 1 FA 0„ 〜 1 FA 3„) を使うことになっている。気を付けるよ一に。
242 試験に出るXI
さて, OPM には 256 ( — び)個のレジスタがあるわけだ。そして,これらのレジスタに
それなりの値を 書き込む ことによって,さまざまな音を出せるのである。この点は PSG
( AY -3-8910) と似たよ一なものである。そしてレジスタに値を入れる方法であるが,たと
えば 21„番 レジスタに C 3„ を入れるのであれば,
OUT & H 700,& H 21
OUT & H 701, & HC 3
とするのである。まったくの自然体である。
図 11-10PM の I/O アドレス
070 Oh
YM2151 T ドレスポート
OUT
0701h
YM2151 データボート
IN/OUT
0704,,
CTC チヤンネル 0
IN/OUT 1
070511
CTC チヤンネル 1
IN/OUT
0706 H
CTC チヤンネル 2
IN/OUT
070711 1
CTC チヤンネル 3
_ ■ ■■ ■ ■ ■ ^
IN/OUT
図 11-2, 11-3 がそのレジスタマップである。このマップは基本的に 00 H 番〜 1 F „ 番(途
中で所々で抜けているが)と, 20 H 〜 FF H の二つの部分に分かれているわけだ。アドレスの
見方にちょっと注意が必要だからそのつもりで。
それで,図 11-3 を見ると分かるように, 0 P 2 と 0 P 3 でレジスタ番号が逆転してい
図 11-2 レジスタマップ ( 00 H 〜 IFm)
レジスタ 番号
1 — ■
D 7 D 彡 Ds D< D 3 D 2 Di Do
上
OlH test
_ *
| LF0 i
RESET
- ⑽ ' 一 z
—
0P4
L
OP マ
0P3
フタ I
0P2 ! 0P1 1
CH No.
OFh NE
""" - ^
■
NFREQ
10m
CLK Ai
h- - -
11h
^ ^—
CLK A 2
12.1
CLK B
14.1 :
CMS
— 1
/
1 FRESET IRQ EN
LOAD
B フ A B A
B ! A
18m
—
- ■ • ^ i
LFRQ
19h
r
F
f
PMD or AMD
| IB"
L
CTz
CTi
— 1
第11章 FM 音源26
マツブ (20h 〜 FF h )
CHO CHI CH2 CH3 CH4 CH5 CH6 CH7
22h 23h 24h 25h 26h 27m
2Bh 2Ch 2Dh 2E
3E
41h 42h 43h 44h 45h 46h 47h
51h 52h 53h 54h 55h 56h 57h
49h 4Ah 4Bh 4Ch 4Dh 4Eh 4Fh
59h 5Ah 5Bh 5Ch 5Dh 5Eh 5Fh
60h 61h 62h 63h 64h 65h 66h 67h
70h 71h 72h 73h 74h 75h 76h 77h
68h 69m 6Ah 6Bh 6Ch 6Dh 6Eh 6Fh
78h 79h 7 Ah 7Bh 7Ch 7Dh 7Eh 7Fh
88h
98h
82h 83h 84»
91h 92h 93h 94»
89h 8Ah 8Bh 8C»
99h 9Am 9Bh 9C»
85h 86h 87h
95h 96m 97h
8Dh 8Eh 8Fh
9Dm 9Eh 9Fh
AOh AIh A2h A3h A4h A5h A6h A7
BOh BIh B2h B3h B4h B5h B6h B7
A8h A9h AAh ABh ACh ADh AEh AF
B8h B9h BAh BBh BCh BDh BEh BF
COh CIh C2h C3m C4h C5h C6h C7h
DOh DIh D2h D3h D4h D5h D6h D7h
C8h C9m CAh CBh CCh CDh CEh CFh
D8h D9h DAm DBh DCh DDh DEh DFh
EOh
FOh
OP3
0P4
EIh E2h E3h
EIh F2h F3h
E9h EAh EBh
F9h FAh FBh
E4h E5h E6h
F4h F5h F6h
ECh EDh EEh
FCh FDh FEh
E7h
F7h
EFh
FFh
る。私は連載時にここでタコってしまってわんわんわわん,わんわんわわんだっ
たのである。 YAMAHA は一体どういう理由でこんなことをしたのであろうか? まった
く理解に苦しむのである。
ところで,「レジスタに書き込むのは分かったが,それじゃ読み出せるのか?」という疑
問が湧くであろう。実はレジスタの値は読み出せないのである。その代わりと言ってはな
んだが, OPM では,
INP (& H 701)
244 試験に出る XI
図 11-4 701 h からの入力の内容
〇7
Di Do
OPM BUSY
1 ST
タイマ A
オーバーフロ
タイマ B
オーバーフロー
とすると,図 11-4 のようなステータスが得られるのである。これにおいて,ビット7は「た
だいま私こと OPM は BUSY ですので,データを OUT しないでください」ということな
のである。 OPM のマニュアルによると直前にデータを書き込んだ後64クロックの間
BUSY になるそうである。よって本当はこのビットが0になっていることを確認してから
データを送らなければならないのであるが,64クロックといえばあっという間であるから
よほどのことがない限り無視してよいだろう。ビット1, 0の 1 ST (たぶんインタラブト •
ステータスのことであろう)というのは オーバーフロー (割り込み)を起こした ( OPM 内
蔵の)タイマを示しているのだが, CZ -8 BS 1 ではこれらの割り込み機能は使えない(使う
必要もない)ので説明はしない。どうしても知りたい人は参考文献6の YM 2151のマニュ
アルを見ていただきたい。また, CZ -8 BS 1 を持っている人ならば「取扱説明書」も持って
いるはずであるから,それも参考にしていただきたい。
ではここからねっとりと解説するのであるが,ここの解説だけで OPM がきちんと理解
できるとは思わないように。シンセサイザの世界は,また一味違ったその筋な世界らし
いのである。
OPM 访基本
OPM には8チャンネル (8 ボイス)があるわけなのだが,それぞれのチャンネルはさら
に4個のオペレータを組み合わせることによってでき上がっている。その四つのオペレー
夕の組み合わせ方には8パターンが用意されていて,それが「アルゴリズム」と呼ばれる
ものである0そのアルゴリズムを図 11-5 に示す0 VIP ( CZ -8 BS 1 に付属のソフト)ではど
ういうわけか1〜8となっているのだが,ここでは〇〜7として説明する。ところで,こ
れら八つのアルゴリズムを見ると,1番 (0 P 1) にだけ自分から出て,また自分に戻る道筋
が書かれていることに気付くであろう。これが フィードバック (FEED BACK ) というや
つである。後で出てくるから覚えておくよ一に。
オペレータとは 一体い かなる もの かとい うと,基本的にこれは「サイン波発生回路」な
のである。ただし単純にサイン波を出すだけのものではなく,あれこれといじることが可
能で,それを利用していろいろな音を作れるのである。
さて,シンセサイザのイロハとも言えるのが図 11-6 の「エンべローブ」である ( SSG :
第11章 FM 音源2ィ5
図 11-5 アルゴリズム8態
アルゴリズ厶〇
アルゴリズ厶1
アルゴリズ厶2
アルゴリズ厶3
—crn
1
\ T \-\_2\
アルゴリズ厶4
アルゴリ ズム5
アルゴリズ厶6
アルゴリズ厶7
_ i _
|4 J [3] [2]
0[3][2][S
1
AY -3-8910 のエンベロープとはちよいと違うので注意)〇これは例のアタツクレート,ディ
ケイレート,サスティーンレート,サスティーンレベル,リリースレートというやつであ
る。これは出力の時間変化なのである。で,先程も害いたように 0 PM には8チャンネルあ
り,それぞれにオペレータが4個ずつあるのである。つまり全部で8 x 4 =32個のオペレ
一夕がある。そして恐ろしいことに,これら32個のオペレータに,それぞれ独立にエンべ
ローブを指定できるのである。さらにはそれぞれのオペレータの周波数を 0.5 倍〜 25.95
倍の間でずらしたり,さらには微妙にプラス/マィナスしたりも可能なのである。つまりは
そのよ一にして,微妙に周波数,出力をずらしたサイン波発生回路をあれこれと組み合わ
せて音を作っていくのである。そしてこれが肝心なのだが, FM 音源において「組み合わ
せ」というのは「足し合わせる」だけではなく,重関数も可能なのである。すなわち,
SIN (2 a > t + d ,)+ SIN ( a > t + d 2 )
のようなタイプだけではなく,
SIN ( a ; SIN (2 a;t + d l )+ d 2 )
などのような組み合わせができるのである。で,オペレータは4個もあるわけだ。さらに
OP 1 は自分の出力を自分に与えたりもできるのである。となると,
SIN ( SIN ( SIN (-)+ d I )+ d 2 )
というような波形を作ることもできるのである。となれば,「これだけ複雑なことができる
246 試験に出る XI
のだから,きっといろんな音を出すことができるような気がする」であろう。ほ〜ら,あ
なたはだんだんそんな気になってきた。ワン,ツウ,スリーである。
OPM 勿しジス9てあ3
というところで,ねっとりとレジスタの解説を始めるのである0
• 01„ : LFO RESET (TEST)
このレジスタはもともと工場でのテスト用にあるものだが,このレジスタの第1ビット
を立ち下げると(「1」 —「0J) LFO のリセットが行なわれる。
LFO とは Low Frequency Oscillator =低周波発振回路のことである。これは音を微妙
に靄わせるために付いているのだ。音の震わせ方には,
ビブラート:音程(周波数)が上下する
トレモロ:音 M (音の大きさ)が上下する
の2とおりがある。 LFO はこれらの「震え」の種になるものなのである。 LFO には図 11-7
に示すような波形が用意されており,リセットとはこれらの「波形の左端から始めるよう
にする」ということなのである0
ちなみに SSG (AY-3-8910) の「エンベロープ」はトレモロに相当するものである0
図 11-7 LFO の波形
08„ : KEY ON/OFF
これはそれぞれのチャンネルのそれぞれのオペレータの ON/OFF を指定するものであ
〇たとえばこのレジスタに 「1011010 b 」 を害き込むと,下3ビットが 010 B = 2で,その
第11章 FM 音源247
上の 4 ビットが 1011 B だから,チャンネル2の OP 4, OP 2, OP 1 が ON , OP 3 が OFF にな
るのである 0 たいていの場合はオペレータをすべて使うから,ここにチャンネルナンバー
を書けば OFF , それに + 1111000 B = 78 H したものを書けば ON ということになる。
• 0 F h : NE/NFREQ
OPM では第7チャンネルの OP 4 だけがノイズモードを持っているのである。 NE = 1
でノイズモードになる。 NFREQ は SSG の R 6 (ノイズ周波数)と同じようなものであ
る。5ビット幅で大体の周波数を決めるのである。ノイズに周波数というのも変なのであ
るが,ま,そんなものなのである。ところで OPM ではこのノイズ機能はほとんどお呼びで
はないのである。現実に VIP はこの機能を使っていないのである。なぜかというと,フィ
ー ドバックを使うとノイズに近い音が出せてしまうからなのである。よって「チャンネル
7の OP 4 だけ」という制限も加わって,この機能は無視する。
•10 H , 11 H , 12„ : CLKA , B
これは OPM 内蔵のタイマの設定値である。 CZ -8 BS 1 では使わないのでいい加減に説明
しておく。まずタイマ A は10ビットからなる。 A ! が上位, A 2 が下位である。その10ビッ
卜の値 (0 〜 1023) を N A とすると,タイマ A の周期 T A は,
^ _ 64 x (1024 — N a )
Ta — ^ -
となる。 f M は OPM に供給されているクロックで, XI では 4 MHz である。よって T A の最
大値は 16.38 ms , 最小値は16 // s である。
タイマ B は8ビットで,
T _ 1024 X (256- CLKB )
“一 fM
となっている。よって, 256// S く T B <65.536 ms である。
•14 H :タイマコン トロール
LOAD がタイマの動作開始, IRQEN が割り込みを起こすかどうかのフラグ ( CZ -8 BS 1
では使えない ), F RESET がオーバーフローフラグ(前述の 1 ST である)のリセットとな
っている。どれも「1」で機能する。 CSM = 1とするとタイマ A がオーバーフローしたと
きにすべてのオペレータを同時に ON にすることができる 0 ちょっと目には便利そうであ
るが,割り込み機能が使えないのでほとんど意味がない。ちなみになぜこの割り込み機能
が使えないかというと, Z 80 のモード2の割り込みに対応できないからなのだ。 PIO を間に
入れればどうにかできるが,それならいっそのこと汎用性の高い CTC を使ってしまえと
いうことになる。
なお,オーバーフローが起きれば 1 ST の対応するビットは1になっている。
• 18„ : LFRQ
LFO の周波数を決めるレジスタである。 LFRQ の値と実際の周波数の関係は表 11-1 の
ようになっている。この表には規則性があって,
f . f M x 2_, ⑹
い4295 XIO ^"
248 试験に出る XI
となっている。
表 11-1 LFO の周波数
LFRQ
周波 K
I (Hz)|
■■ ■ .
LFR0 周波数
j LFRQ (Hz)
LFRQ
用波教
(Hz)
LFRQ
FF
59.1278
m «
BF
3.6955
7F
0.2310
3F 0.0144
FE
57.2205
BE
3.5763
7E
0.2235
3E 0.0140
FD
55.3131
BD
3.4571
7D
0.2161
3D 0.0135
FC
53.4058
BC
3.3379
7C
0.2086
3C 0.0130
FB
51.4984
BB
3.2187
7B
0.2012
3B 0.0126
FA
49.5911
BA
3.0994
7A
0.1937
3A 0.0121
F9
47.6837
B9
2.9802
79
0.1863
39 0.0116
F8
45.7764
B8
2.8610
78
0.1788
| 38 0.0112
F7
43.8690
B7
2.7418
77
0.1714
37 0.0107
F6
41.9617
B6
2.6226
76
0.1639
36 0.0102
F5
40.0543
B5
2.5034
75
0.1565
35 0.0098
F4
38.1470
B4
2.3842
74
0.1490
34 0.0093
F3
36.2396
B3
2.2650
73
0.1416
33 0.0088
F2
34.3323
B2
2.1458
72
0.1341
32 0.0084
F1
32.4249
B1
2.0266
71
0.1267
31 0.0079
F0
30.5176
BO
1.9073
70
0.1192
30 0.0075
EF
29.5639
AF
1.8477
6F
0.1155
2F 0.0072
EE
28.6102
AE
1.7881
6E
0.1118
2E 0.0070
ED
27.6566
AD
1.7285
6D
0.1080
2D 0.0068
EC
26.7029
AC
1.6689
6C
0.1043
2C 0.0065
EB
25.7492
AB
1.6093
6B
0.1006
2B 0.0063
EA
24.7955
AA
1.5497
6A
0.0969
2A 0.0061
E9
23.8419
A9
1.4901
69
0.0931
29 0.0058
E8
22.8882
A8
1.4305
68
0.0894
28 0.0056
E7
21.9345
A7
1.3709
67
0.0857
27 0.0054
E6
20.9808
A6
1.3113
66
0.0820
26 0.0051
E5
20.0272
A5
1.2517
65
0.0782
25 0.0049
E4
19.0735
A4
1.1921
64
0.0745
24 0.0047
E3
:18.1198
A3
1.1325
63
0.0708
23 0.0044
E2
17.1661
A2 l
1.0729
62
0.0671
22 0.0042
E1
16.2125
A1
1.0133
61
0.0633
21 0.0040
E0
15.2588
AO
0.9537
60
0.0596
20 0.0037
DF
14.7820
9F
0.9239
5F
0.0577
IF 0.0036
DE
14.3051
9E
0.8941
5E
0.0559
IE 0.0035
DD
13.8283 9D
0.8643
5D
0.0540
ID 0.0034
DC
13.3514
9C
0.8345
5C
0.0522 *
1C 0.0033
DB
12.8746
9B
0.8047
5B
0.0503
IB 0.0031
0A
12.3978
9A
0.7749
5A
0.0484
1A 0.0030
D9
11.9209
99
0.7451
59
0.0466
19 0.0029
D8
11.4441
98
0.7153
58
0.0447
18 0.0028
D7
10.9673
97
0.6855
57
0.0428
17 0.0027
D6
10.4904
96
0.6557
56
0.0410
16 0.0026
D5
10.0136
95
0.6258
55
0.0391
15 0.0024
D4
9.5367
94
0.5960
54
0.0373
14 0.0023
D3
9.0599
93
0.5662
53
0.0354
13 0.0022
D2
8.5831
92
0.5364
52
0.0335
12 0.0021
D1
8.1062
91
0.5066
51
0.0317
11 0.0020
DO
7.6294
90
0.4768
50
0.0298
10 0.0019
CF
7.3910
8F
0.4619
4F
0.0289
OF 0.0018
CE
7.1526
8E
0.4470
4E
0.0279
OE 0.0017
CD
6.9141
8D
0.4321
40
0.0270
OD 0.0017
CC
6.6757
8C
0.4172
4C
0.0261
OC 0.0016
CB
6.4373
8B
0.4023
4B
0.0251
OB 0.0016
CA
6.1989
8A
0.3874
4A
0.0242
OA 0.0015
C9
5.9605
89
0.3725
49
0.0233
09 0.0015
C8
5.7220
88
0.3576
48
0.0224
08 0.0014
C7
5.4836
87
0.3427
47
0.0214
07 0.0013
C6
5.2452
86
0.3278
46
0.0205
06 0.0013
C5
5.0068
85
0.3129
45
0.0196
05 0.0012
C4
4.7684
84
0.2980
44
0.0186
04 0.0012
C3 l
4.5300
83
0.2831
43
0.0177
03 0.0011
C2
4.2915
82
0.2682
42
0.0168
02 0.0010
Cl
4.0531
81
0.2533
41
0.0158
01 0.0010
CO
3.8147
80
0.2384
40
0.0149
00 0.0009
— - ^ - 量
第11章 FM 音源2外
•19 H : F,PMD or AMD
ビット 7 は指定した値が PMD 用であるか AMD 用であるかを区別するためのものであ
る。 F = 1で PMD に, F = 0で AMD に使われる。想像するに, OPM の内部には PMD 用
と AMD 用の二つの7ビットの隠れワークエリアがあるのだ。そしてビット7二 F は,ビ
ット〇〜6の値を PMD のワークエリアの方に送るか,それとも AMD の方に送るかのフ
ラグになっているわけである。
AMD , PMD は〇〜127の値を設定するわけだが,これは早い話が, LFO のかかり具合
を決めるものである。ただし,ここだけですベて決まるものではない。詳しくは後程説明
する。
ところでど一して素直に1%と 1 A H の二つのレジスタに分けなかったのだろう0不可解
である。
•1 B H : CTi , CT 2 , W
CT m CT 2 は外部をコントロールするためのものである。 YM 2151 には CT m CT 2 という
ピンがあって,そこに直行しているのである。つまり2ビットだけの汎用出カポートであ
る。 XI では使えない。
W は LFO の波形を指定するものである。値と波形の関係は図 11-7 である。 LFO が
PMD に使われるか AMD に使われるかで少し違うことに注意。
ここから先は図 11-3 の方に差しかかってくるわけである〇 8個のチャンネルはすべて同
じであるからこれから先はチャンネル0を対象とする。もしもチャンネル3を扱うのなら
レジスタ番号を+ 3すればよいだけ(以下同様)の話なのである。
• 20„ : RL , FB f ALG
ビット7, 6はそのチャンネルの出力の右左を決めるものである0図 11-3 では左側にな
っ ているビット7が R (右出力指定)でビット6が L であることに注意0 FB は OP 1 の フィ
ー ドバック(自己変調)の深さを決めるものである。0ならば自己変調はなしである。資
料には表 11-2 が載っているが, 「; r /8」 が一体何を表しているのかは,私の知ったことで
はない。とにかく FB を大きくするとノイズっぽい「ジャ〜ン」という音になっていく。
ALG は前述のアルゴリズムを指定するものである。
表 11-2 フィードバックの深さ
I _ ■ - T ■ ■ マ国^
FB
0
1
- -つ
2
, ■■一 1
3
4
5
6
7
レペル
OFF
; r / 16
t/8
t /4
T/ 2
n
2 n
_1
• 28„ : KEY CODE
• 30„ : KEY FRACTION
これは音階を指定するレジスタである 。 KEY CODE の方はドレミの音階 , KEY
FRACTION の方は微調整用である(半音=100セントとして 1.6 セント刻みで64段階二
〇〜100.8セントを調整できる)。さて, OPM は実は 3.58 MHz で使うように設計されて
いるのだが, CZ -8 BS 1 では 4 MHz で動かしているのだ。よって音階の指定は本来のデータ
と違ってしまうのである。それでどうするかというと , KEY FRACTION に5を指定
250 試験に出る XI
し,後は KEY CODE を半音二つ分下げてやるのである。よって本来の 3.58 MHz では
ド,レ,ミ,ファ, ソ,ラ,シ,ドは,
3 E ", 41h , 44 h ,45 h , 48 h ,4 Ah ,4 Dh , 4Eh
に対応するのであるが, CZ -8 BS 1 では,
3Ch , 3Eh , 41h , 42h , 45h , 48h , 4Ch
となるのである。ドが「 ? C H 」 になったのであるから分かりやすくなったとも思えるがよ
う分からん。なお , KEY CODE に 10 H を加えると1オクターブ上の音になるのである。表
11-3 を参照のこと。
表 11-3 4 MHz 動作時のキーコード (KEY FRACTION = 5とすること)
KEY CODE
+ 0Ch
+ 0Dh;+0Eh
里
+ 0Fh| + 10h +11 H . + 12 H +13h +14hi + 15h
[ 1 ]
+ 16h
1 1 |
+17h
+ 18h
+ 19h +1Ah, + 1Bm
III
音 程
c
L — —,
1■ ■ J
1
D
r ]
(D5)
- - V - T -
D# E F
(F«)
F#
—■ — u
G
G»
—
㈧
A
- - T - -
A« B
- 1
( + C)
• 38„ : PMS , AMS
これは19„の PMD or AMD と関係あるところである。後でまとめて解説する。
❿40„以降はレジスタ番号順ではなく,機能ごとにまとめて説明する0
① AR,1DR, 2DR,1D し, RR, T し, KS
これらは エンベロープに 関係するパラメータである。 図 11-8 に 示したような機能を持っ
ている。図からは逆のような感じがするかもしれないが, AR (アタックレート), 1 DR (フ
アー ストディケイレート), 2 DR (セカンドディケイレート ), RR (リリースレート)は大
きければ大きいほど エンべローブの 変化が速くなるのである。 1 DL (フ アース トデイケイレ
ベル) は少し違って, 1 DR —2 DR の切り換え点を示すものである。 AR で最大に達した出
図 11-8 エンベロープ指定のパラメータ
音置
第11章 FM 音源257
表 11-5 出力変化時間表
A 10%—90%
B 0 %一 100%
ATTACK TIME
_ - - *
- ,
DECAY TIME
BP
mivmvM
* — ,
RATE
1
ms(0%— 100%)
RATE
ms(100%—0%) |
63
0.00 I
l
63
SSI
■- 一 ]
63
0.00
63
6.02
62
0.24
62
1.22
62
0.47
62
6.02
61
0.24
61
1.22
61
0.47
61
6.02
60
0.24
60
1.22
60
0.47
60
6.02
59
0.30
59
1.39
59
0.57
59
8.03 I
252 试験に出る XI
力が 1DR で指定された速度で 1DL 分減ったところで滅り方が 2DR に従つよつに切り換
えられるのである。つまり,
1) AR :キーオンになったら,とにかくこの速さで最大の出力に達しなさい(キーオ
ン,キーオフはレジスタ 08 H で指定するんでしたねっ)〇
2) 1DR : AR で最大に達した後はこの速さで減っていきなさい。ただし 1DL で指定さ
れた分だけですよ。
3) 2DR : 1DL 分減りましたね。では今からこの 2DR で指定する速さで減っていきな
さい。ただしキーオフになるまでです。
4) RR :キーオフ(二なった後は RR で指定した速さで減りなさい。はいよくできまし
た。
となっているのである0そして最後の TL (トータルレベル)は要するに音 M なのであ
る。 TL は 0 で最大, 127 で最小の出力となる。逆であるから注意のこと。
で,問題は「速さ」は具体的にどうなっているのかである。それは表 11-4, 11-5 なので
あるが,これには KS (キースケーリング)が絡んでくるのである。キースケーリングとは
どういうものかというと,
音の高さに応じてエンベロープの変化も速くする (そういうモードも付けておこう)
表 11-4 KS, KC -Rks
3 6789012345678901
こ 1111222222222233
2 8899101011111212131314141515
1 444455556666
〇 2222222233333333
S
K
6789012345678901
1111222222222233
3
0123456789101112131415
2 00112233445566
0000111122223333
〇 〇 〇 〇 〇 r-H r-H r-H r-H
0123456789 101112131415
0.67
0.81
1.00
1.09
1.27
1.53
1.91
1.99
2.33
2.78
3.48
3.98
4.65
5.58
6.97
7.97
9.29
11.15
13.94
15.93
18.58
22.30
27.88
31.86
41.53
44.60
55.75
63.72
74.34
89.20
111.51
127.43
148.68
178.41
223.01
254.87
297.35
356.82
446.02
509.74
594.69
713.63
892.04
1019.48
1189.38
1427.27
1784.08
2038.95
2378.78
2854.53
3568.16
4077.90
4757.55
5709.06
7136.33
無限大
無限大
無限大
無限大
8.03
9.63
12.04
I 13.77
16.06
19.27
24.08
I 27.52
! 32.11 |
I 38.53 :
48.16
55.04
64.22 I
; 77.06
96.33
110.09
128.43 I
154.12 |
192.65 1
220.17
212.12 |
308.25
385.31
440.35 I
513.74
616.48
770.60
835.95
1027.48
1232.97
1541.22
1761.39
2296.04
2465.94
3082.42
3522.77
4109.90
4931.89
6164.86
7045.55
8228.76
9863.77
12329.71
14091.09
16439.61
19727.54
24659.42
28182.20
32879.23
39455.07
49318.84
56364.40
65758.46
78910.15
98637.69
無限大
無限大
無限大
無限大
1.62
1.95
2.43
2.78
3.26
3.89
4.87
5.57
6.49
7.79
9.74
11.12
12.99
15.58
19.48
22.26
25.96
31.16
38.95
44.52
52.83
62.32
77.90
89.03
103.86
124.64
155.80
177.43
207.74
249.28
311.60
356.12
415.47
498.57
623.21
712.23
830.94
997.13
1246.41
1424.47
1661.88
1994.26
2492.83
2848.95
3323.77
3988.52
4985.65
5697.88
6647.53
7977.05
9971.30
11395.78
13295.07
15954.08
19942.60
無限大
無限大
無限大
無限大
58
57
56
55
54
53
52
51
50
49
48
1 47
46
45
44
43
42
41
40
39
38
37
36
| 35
34
! 33
32
31
30
29
28
I 27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
I 7
6
5
S ^
2
1
0
0.36
0.42
0.59
0.55
0.65
0.78
0.98
1.12
1.31
1.57
1.96
2.24
2.61
3.13
3.91
4.48
5.22
6.27
7.87
8.95
10.44
12.52
15.65
17.89
20.87
25.05
31.32
35.78
41.75
50.10
62.62
71.57
83.50
100.20
125.26
143.15
167.01
200.40
250.50
286.29
334.01
400.81
501.01
572.59
668.01
801.62
1002.02
1145.16
1336.02
1603.23
2004.04
2290.32
2672.05
3206.45
4008.07
無限大
無限大
無限大
無限大
8765432109876543210987654321098765432109876543210) J
55555555544444444443333333 33 32222222222111111111198
76543210
876543210987654321098765432109876543210987654321 }). )
555555555444444444433333333332222222222111111111192765432 1C
5857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111098765432 10
第 11 章 FM 音 m 253
というものである。保証の限りではないがそうした方がより自然な音色になるそうなので
ある。ではキースケーリングを説明する。
まずは R を求める。 AR ,1 DR , 2 DR の場合ならばそれらの値(レジスタに書き込んだ
値)が R そのものであるが,そうではなくて,もしも RR の場合ならば,
R=2XRR+ 1
とするのである。
次に表 11-4 を使って R KS を求める。横のカギが KS (0 〜3),縦のカギが KEY CODE
の上位5ビット = KC (0 〜 31) である。たとえば KS =2 ,KEY C 0 DE = 2 E „ 二010111 Ob
とすると,^ = 01011 8 =11となるので表より Rks は5となる。
尺と R KS が求められたならば,
RATE 二 MAX (2 xR + R KS ,63)
とする。つまり, RATE の上限を63に制限するのである。この RATE を使い,表11 -5
A ,11-5 B から時間を計算することになる。表 11-5 A の方は出力が10%- 90 %の変化を
する時問,表 11-5 B の方は0 %— 100 %の変化をする時問となっている。で,両方の表と
も左側はアタックレート ( AR ) によって増加する時間,右側はディケイレート (1 DR ,
2 DR , RR ) によって減少する時間である。単位はすべて ms ( 1 /1000秒)となってい
る。
あと説明が必要なのが 1 DL であるが,これは,
減衰 M = lDLx 3( dB )
となっている。ただし, 1 DL が最大の15のときはさらに+48 dB することになっている(つ
まり最大減衰 M は 15 X 3 + 48 = 93 dB ) 0 dB とは減衰 M を表す単位で,デシベルと読む〇べ
ルとは電話を発明したグラハム • ベルに由来した単位である0 TL の方は,
減衰 M = TLx 0.75( dB )
となっており,これの最大減衰は 95.25 dB である。大体の目安となるであろう。
② DTI, DT2,MUL
これら KEY CODE と KEY FRACTION で決めた周波数を微調節するパラメータであ
る。 KEY CODE と KEY FRACTION は各チャンネルに一つだが, DTI , DT 2 ,MUL
は各オペレータごとに設定が可能である 0 すなわち 一つの チャンネルでオペレータが別々 の
周波数で動作するのだ。まずは表 11-6 である。横のヵギが MUL (0 〜 15), 縦のカギ
が DT 2 (0 〜 3) である。この表から得られた値を Fr (FREQUENCY RATIO ) と
する。
« 11-6. DT 2, MU い Fr 表
• DT 2 、、、一
0
1
I " I
2
3
4
5
6
7
"
8
9
» *
10
11
!12
13
14
15
0.50
1.00
2.00
3.00
4.00
5.00
6.00
7.00
l
8.00
1 - V -
9.0010.00
r <
11.00
12.00
~T
13:00
14.00
15.00
D^a
2.82
7.07
1 1
8.46
9.89
11.30
■ f ■ 11
12.72 14.10,
15.55
16.96
18.37
19.78
21.20
—
6.28
12.5614.13
J _ J _ _
15.70
17.27
18.84
20.41
21.98
23.55
3— v 3倍
0.87
1.73
3.46
5.19
6.92
20.76
22.49
24.22
25.95
254 試験に出る XI
表 11-7 KC , DTI—Fd 表
\dti
セン
卜 ( 半音 =
: 100 セント)
Hz
_ _ __ •
KC \
01
±1
土 2
士 3
0
±1
土 2
±3
0
0.000
0.000
5.025
10.036
0.000
0.000
0.053
0.107
1
0.000
0.000
4.228
8.445
0.000
0.000
0.053
2
0.000
0.000
3.559
7.110
0.000
0.000
0.053
0.107
3
0.000
0.000
2.993
5.980
0.000
0.000
0.053
0.107
4
0.000
2.515
5.025
5.025
0.000
0.053
0.107
0.107
5
0.000
2.115
4.228
6.338
0.000
0.053
0.107
0.160
6
0.000
1.778
3.555
5.330
0.000
0.053
0.107
0.160
7
0.000
1.496
2.990
4.483
0.000
0.053
0.107
0.160
8
0.000
1.258
2.515
5.025
0.000
0.053
0.107
0.213
9
0.000
1.057
3.170
4.225
0.000
0.053
0.160
0.213
10
0.000
0.889
2.667
3.555
0.000
0.053
0.160
0.213
11
0.000
0.748
2.242
3.735
0.000
0.053
0.160
0.267
12
0.000
1.258
2.515
3.143
0.000
0.107
0.213
0.267
13
0.000
1.057
2.114
3.170
0.000
0.107
0.213
0.320
14
0.000
0.889
1.778
2.667
0.000
0.107
0.213
0.320
15
0.000
0.748
1.869
2.615
0.000
0.107
0.267
0.373
16
0.000
0.629
1 1.572
2.515
0.000
0.107
0.267
0.427
17
0.000
0.793
1.566
2.114
0.000
0.160
0.320
0.427
18
0.000
0.667
1.334
2.001
0.000
0.160
0.320
0.480
19
0.000
0.561
1.308
1.869
0.000
0.160
0.373
0.533
20
0.000
0.629
1.258
1.729
0.000
0.213
0.427
0.587
21
0.000
0.529
1.057
1.566
0.000
0.213
0.427
0.640
22
0.000
0.445
1.001
1.445
0.000
0.213
0.480
0.693
23
0.000
0.467
0.935
1.308
0.000 1
0.267
0.533
0.747
24
0.000
0.393
0.865
1.258
0.000
0.267
0.587
0.853
25
0.000
0.397
0.793
1.123
0.000
0.320
0.640
0.907
26
0.000
0.334
0.723
1.056
0.000
0.320 j
0.693
1.013
1 27
0.000
0.327
0.654
0.935
0.000
0.373
0.747
1.067
28
0.000
0.315
0.629
0.865
0.000
0.427
0.853
1.173
29
0.000
0.315
0.629
0.865
0.000
0.427
0.853
1.173
30
0.000
0.315
0.629
0.865
0.000
0.727
0.853
1.173
! 31
0.000 ,
0.315
0.629
0.865
0.000
0.427
0.853
1.173
次に DTI (— 3 〜 +3) と,先程出てきた KEY CODE の上位5ビット分の値, KC を
使って 表 11-7 から Fd を得る。 DT 1 はレジスタ40„〜 5 F H の第6, 5,4ビットである
が,第6ビットを符号ビットと解釈するのである。そして Fd と DT 1 の符号は同じにする
こと 0 つまり KC = 11, DT 1 = —2であったなら, Fd = — 0.160( Hz ) = — 2.242(セント)
となる。
以上のように Fr と Fd が求められたなら , KEY CODE と KEY FRACTION ( + LFO
による震え)で決まっていた周波数 F に対して,
F = FxFr + Fd
としてこの F を各オペレータの周波数とするのである0繰り返すが F は各オペレータごと
に変えることができるのである。
③ PMD, AMD, PMS, AMS, AMD_EN
いよいよ最後である。これは 図 11 - 9 を見ていただくと一目瞭然であろう。そして , PMD
or AMD が最大(つまり 127) のときの PMS のかかり具合は 表 11-8 である。 PMS = 7の
第 11 章 FM 音源 255
図 11-9 パラメータの流れ
表 11-8 PMS による変調度 ( PMD =127 のとき)
PMS
0
\ ■ —— ■ 1
1
2
3
4
5
6
7
最大変 M 度(セント)
(半音=100セント)
0
± 5
1
±10
土 20
■ _ ■ ■— ■_」
±50
—_ _ J
土 100
土 400
L - 1
土 700
ときは700セントであるから,つまりは半音7個分なのである。 AMD の方は,減衰 M は
AMD = 0 — OdB , 1 — 23.90625 dB ,2 — 47.8125 dB , 3 — 95.625 dB となっている 。 TL に
よる最大減衰 M : が 95.25 dB であるから,要するに AMD を最大限にかけると谷底で出力は
0になってしまうのである。
というところで OPM のレジスタの説明は終わりである。これだけではわけが分からな
いかもしれないので, ちょいとサン ブルを載せておく。 リスト 11-1 が VIP の NEWTONE
から持ってきたピアノの音色データである。 リスト 11-2 の231〜232行を挿入して,480行
以降を害き換えるとドミソの和音となる。なおデータ文中の数値は2桁ならば16進数,
1桁もしくは3桁ならば10進数,それ以外ならば2進数と解釈されるようになってい
る。データ分を適当に書き換えて OPM をいじりまわしていただきたい。
リスト1卜1ピアノ ___
100 READ RS : R1$=LEFTS(RS ,1 ) : IF Rl$="!" THEN END
110 IF R1$="P" THEN PAUSE VAL(MID$(R$ f 2 f 255)) : GOTO 100
120 R=VAL("&H"+R$>
130 READ DS : DL=INSTR(D$ f ,f >
140 IF DL=0 THEN DL=LEN(D$)+1
256 試験に出る XI
(&H28<=R) AND (R<=&H2F) THEN 240
(R>=&H20) THEN FOR L=0 TO 2:GOSUB240:R=R+1:NEXT:RETUR
480 DATA 28,3C , 29,41 , 2A,45
490 DATA 08,78 f P4 f 08,79,P4 f 08 f 7A f P4
500 DATA 08-00,08,01,08,02
510 DATA 08.78 , 08,79 , 08,7A,P9
520 DATA 08,00,08,01,08,02,P6
530 DATA !
2
卜ダイアラであ 3
これから MML の作成に取りかかるわけであるが,その前に FM 音源の,なかなかにそ
の筋な使い方を発見したので紹介しておくのである。それは FM 音源で電話をかけてしま
おうというものである。つまりトーンダイアラなわけだ。ただしこれはブッシュホンだけ
第11章 FM 音源257
ソ用変更点
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
ON DL GOTO 170 , 170 , 180,170
E$="&B":GOTO190
E$ = ". •: GOTO190
E$="&H"
D = VAL(E$-fD$) : 1 IF DO0 THEN PRINTHEXS(R)
GOSUB"SFM":GOTO 100
,D
LABEL m SFM m
f WHILE(INPJ&H701)
OUT &H700 f R
OUT &H701 f D
RETURN
AND &H80) : WEND
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
01,02,01,00 : ,TEST
08,00,08,01,08 , 02 , 08 , 03:,KEY OFF (0-3)
08,04 ,08,05, 08,06,08,07:»KEY OFF (4-7)
0F f 00000000 : f NE/FREQ
10,00 , 11 , 00 , 12 , 00 , 14,00: ,CLK A1,A2,B
18,220
19,00000100
1B, 00000010
20,11111010
30,00010100
38,00010001
40,01010001
50,01110001
48,00100101
58,00010001
60 , 037 ,70.062,68
LFRQ
PMD/AMD
CT/W
RL/FL/CON
KF
PMS/AMS
DT1/MUL(1)
DT1/MUU2)
DTI/MU し <3>
58,00010001 : f DTl/MUL(4)
60,037 ,70 ,062 ,68,077,78 ,010: , TL(1-4)
80 , 5 F , 90 , 56,88 , 5D, 98,9 F: f KS/AR(1-4)
A0 f 05 f B0 f 00 f A8 f 00 f B8,87 :, AMS-EN/D1R(1-4
C0 , 07•D0,04,C8,04,D8 , 06: , DT2/D2R(4 >
E0•94•F0 , 45 , E8,45,F8 , 45: , D1L/RR(4)
28 , 3C, 08,78 ,P 9 , 08 ,00,P6
28,3E f 08,78 f P9 f 08 f 00,P6
28 f 41 f 08 t 78 f P9 f 08,00 f P6
28 f 42,08, 78 f P9 f 08,00 # P6
28 f 45,08, 78 f P9 # 08 f 00 f P6
28,48,08,78 f P9,08 f 00,P6
28,4A.08,78 , P9, 08 , 00 ,P6
28,4 C, 08,78 , P9,08,00 , P6
F F
1 ^
12
3 3
2 2
000000000000
567890123456
に有効なヮザである(世の中には一見するとブッシュホンだが,実はダイヤル式の電話を
押しボタン式に変えただけのものもある。そのような方式だと使えない)。
解説しよう。ブッシュホンは,ボタンを押すとそれに対応した2種類の高さの正弦波が
出るような仕組みになっているのである。例の r ピポパピポ」という音である。で,具体
的にどのような周波数の音が出ているかというとそれが 図 11-10 である。一目瞭然であろ
うが,たとえば「5」のボタンを押すと 770 Hz と 1336 Hz の二つの正弦波が出るのであ
る。ちなみにみんな知っているように,一般の電話機には A , B , C , D のボタンは付いて
いない《しかしこのように決まっているそうである。
図 11-10 押しボタンの配列と周波数の M 係
\高群
低群\
- " 1
1209 Hz 1336 Hz 1477 Hz 1633 Hz
697 Hz
770 Hz
852 Hz
941 Hz
1
4
7
本
2
5
8
0
3
6
9
It
A
B
C
D
さて,ここからが肝心なのであるが,実はプッシュホンでボタンを押して出る「ピポパ
ピポ」の音も,人間が送話口でしゃべる音も,電話回線にとっては同じなのである。よっ
て,正確な周波数で口笛を吹ける人が2人いて,電話機の送話口に向かって「ピポポパ」
と口笛を吹くと,ちゃんと電話がかかってしまうのである。しかし残念なことにそこまで
正確に口笛を吹ける人を2人も連れてくることは難しいので,その代わりに FM 音源を使
ってしまおうというわけである。そしてそれが リスト 11-3 である。使い方は,
1) 正確に打ち込む。
2) 110行を取り去り,120行の REM (’) を消して RUN する。
3) キーボードの数字キーを押し, ブッシュ ホンのボタンを押したときに聞こえる音
と, できるだけ近くなるように ボードに付いているボリウムを調節する0
4) 電話の受話器を取り,送話口をスピーカに近づけ,ピポパする。ただしこのとき117
などのように 緊急電話に近い番号は避ける。 最初は自分の電話番号にかけて,話し中
であることを確認するのがよいであろう。もしも間違い電話になってしまったらよく
謝ること。
というわけで,この機能を使えばソフトだけで(送話口をスピーカに持ってくる必要は
あるが)オートダイヤルできるのである。住所録や電話帳ソフトに期待したい0なお,以
上の行動は NTT から怒られることはないはずであるから安心して使っていただきたい
258 試験に 出る XI
(だってモジュラージャックに直接接続するわけではない)。
ちなみにこのテクニックを応用すれば,ソフトウェアだけで「送信だけの音響カブラ」
ができるはずである(きっと信頼性は最低だろう)。ぜひとも自由研究していただきたい。
リスト 11-3 トーンダイアラ
100 GOSUB”INIT"
110 D$="604 1111":G0SUB 150
120 , D$=INKEY$( 1> :GOSUB 150 : GOTO120
130 END
140 1
150 FOR 1=1 TO LEN(D$)
160 A$=MID$(D$,I f 1):PRINT A $;
170 GOSUB200
180 NEXT:RETURN
190 f
200 T=INSTR( M 123456789 *0# n f AS) : IF T = 0 THEN RETURN
210 T=T-1 : L=T ¥ 3:H = 4«f (T MOD 3)
220 R=8 : D=&H78+L:GOSUB 380
230 R=8:D=&H78+H:GOSUB 380
240 PAUSE 1
250 R=8 : D=L:GOSUB 380
260 R=8 : D=H:GOSUB 380
270 RETURN
280 1
290 LABEL"INIT"
300 READ R$ : R1$ = LEFT$(R$ f 1):IF Rl$ = "!" THEN RETURN
310 R = VAL( M &H M -fMID$(R$ f 1 f 2))
320 M$=MID$(R$ f 3 f l):IF M$<>"-" THEN 340
330 R0 = R : R1=VAL( M 4H M -fMID$ ( R$ f 4 f 2 ) )
340 READ D$ : D=VAL(
350 GOSUB 370:GOTO 300
360 1
370 IF THEN FOR R=R0 TO R1 : GOSUB380 : NEXT : RETURN
380 OUT &H700,R
390 OUT &H701,D
400 RETURN
410 1
420 DATA 01,02,01,00 : , TEST
430 DATA 08,00,08 f 01 f 08,02, 08,03:'KEY OFF (0-3)
440 DATA 08 f 04 f 08 f 05,08,06,08, 07:'KEY OFF (4-7)
450 DATA 0F-1B, 00 : , NE/FREQ".
460 DATA 20-27,47 : , RL/FL/CON
470 DATA 28,51 ,29,54, 2A,56,2B,59:,KCODE (0-3)
480 DATA 2C , 5E,2D,61,2E , 62,2 F,00:,KCODE (4-7)
490 DATA 30,EC,31 , A8,32,6C , 33,24:(0-3)
500 DATA 34,78,35,34,36 f fee,37,00 : , KF (4-7)
510 DATA 38-3F t 00 : f PMS/AMS
520 DATA 40-5F.01 : , DT1/MUL
530 DATA 60-7F,20 : , TL
540 DATA 80-9F,IF : , KS/AR
550 DATA A0-DF # 00 : ’AMS-EN/1DR,DT2/2DR
560 DATA E0-FF,FF : , 1DL/RR
570 DATA !
というところで, FM 音源の具体的な応用として MML (ミュージック•マクロ •ランゲ
ージ:よ一するに BASIC の PLAY 文が多少進化したやつ)を作ったりするわけだ。そし
てあな恐ろしや,なんと BASIC の書き換えに手を染めてしまったのであった。そう,はっ
きり言って私は BASIC の書き換えが嫌い.なのである。なぜかというと,最大の理由は
BASIC というものは結構ちまちまとバグ取りのためにバージョンアップされていたりす
るからである。大抵の場合はそれでもたいした影響はないのであるが,しかしやはりそこ
第11章 FM 音源250
7FD1
A5DB
03
72
CD 5436
CD 5BAF
7C
B5
20 4C
21 4001
22 A9D4
22 A9D6
2B
22 A9D2
44
4D
21 A900
22 2DE3
22 2E11
22 2E13
0704
4000
A8B0
A8B3
A8B6
A8B9
A8BC
A8BD
A900
A903
A906
A907
A908
A90A
A90C
A90F
A912
A913
A914
A916
A919
A91C
A91F
A920
A923
A924
CTC
WTOP
• Z80
.PHASE
0A8B0H
EQU
0704H
EQU
4000H
LD
HL.0A900H
LD
(2DE3H),HL
LD
(2E11H) f HL
LD
(2B13H) f HL
RET
DS
0A900H-KOKO
CALL
7FD1H
LD
A t (0A5DBH)
PUSH
HL
EX
DE f HL
CP
03
JR
Z t DOSTR
A=VAR TYPE
SAVE TEXT PTR
STRING ?
GET STRING
ELSE TEMPO
TEM!
CALL
5436H
;CSNG
CALL
5BAFH
;->INT
LD
A f H
OR
L
JR
NZ f PRET
: TEMPO 0 = INITIALIZE
INIT :
LD
LD
LD
DEC
LD
LD
LD
HL,WTOP+l
(HEAD) f HL
(HEAD0) f HL
HL
(TAIL) t HL
B, H
C. L
INIT POINTERS
BC=HL
はかとなく不安が漂ったりするわけである。もしもどれかのバージヨンではこのよ一な
書き換えが許されなかったりしたら困るのである。しかし使い勝手からすると,どうして
も BASIC の書き換えが必要なのである。困ったものである。
MM し T あ3
リスト1卜4, 11-5, 11-6 である。説明すると,リスト 11-4 がソースリスト ( BASIC を
書き換えるルーチンも含んでいる),リスト 11-5 がそのダンプリスト,リスト 11-6 がサン
ブル曲である。
さて使い方である。まずは NEW ON & HC 000 を実行した後でリスト 11-5 を打ち込
み,チェックサムと CRC を確認する(付録 A を使うこと)。 XI ユーザーであればここま
でである。もしも turbo ユーザーである場合は,さらに次の3か所を変更する。
A 965 : 07 07 — A 31 F
A 9 D 9 :04 07 — AO 1 F
A 9 E 8 :07 07 4 A 31 F
SAVEM ^ MML . OBJ ", & HA 8 B 0, &HAFFF で セーブする。
次に使用方法である。 CZ -8 FB 01 V 1.0 を起動する 。 NEW BASIC ではないし , turbo
BASIC でもない 。 NEW ON & HB 000 を実行した後 , LOADM ^ MML . OBJ " で ロード
し , CALL & HA 8 B 0 を実行。これで MML が使えるようになる。
りスト 11-4 MML ソースリスト
9
C
D A 5 B E 8
C 3 E E F 2
260 試験に出る XI
CD A9D8
21 AA32
22 005E
FB
El
C9
01 0707
3E 03
ED 79
16 07
3E 08
CD ADD5
15
20 FA
CD ADD5
011C00
C3 013F
CD 7FC3
B7
28 03
CD A99F
El
7E
D6 3B
23
C8
2B
ED 4B A9D6
AF
ED 79
03
ED 43 A9D6
ED 43 A9D4
C9
ED 4B A9D6
2A A9D4
B7
ED 42
20 05
2E 3A
ED 69
03
6F
1A
A925
A926
A928
A92A
A92D
A930
A933
A936
A938
A939
A93B
A93C
A93F
A941
A942
A944
A946
A947
A949
A94A
A94C
A94F
A952
A955
A958
A95B
A95E
A961
A962
A963
A964
A967
A969
A96B
A96D
A96F
A972
A973
A975
A978
A97B
A97E
A981
A982
A984
A987
A988
A989
A98B
A98C
A98D
A98E
A992
A993
A995
A996
A99A
A99E
A99F
A9A3
A9A6
A9A7
A9A9
A9AB
A9AD
A9AF
A9B0
A9B1
XOR
OUT
LD
LD
LD
LD
LD
LDIR
INC
LD
DEC
LD
LDIR
; DE=ACTF
EX
LD
INIT0 : LD
INC
DJNZ
A
(C) f A
A f 30
(TMPV),A
HL.DFLDMY
DE f DFLW
BC f 4t9
DUMMY DATA
TEMPO120
TEMPO AREA
INIT DFLW
HL
(HL)
HL
BC f 4
t 12
拿 2
DE 9 HL
B f 11
(HL) f 0
HL
INIT0
; HL=ACTF
••KILL
DI
LD
LD
LD
ID
CALL
CALL
LD
LD
El
A f 0C3H
(13CH) f A
HL f QUIETl
(13DH),HL
013CH
TOCTC
HL,IEXEC
(005EH),HL
QUIET
SET VECTOR
PRET:
POP
HL
•
RET
;STOP
SOUND <
-PSG MUTE
<-"ctrl-D..
QUIET1
: LD
BC,CTC+3
LD
A f 3
•
OUT
<C),A
;RESET CTC
1
LD
LD
D.7
A,8
Q2 :
CALL
WOPM
DEC
D
JR
NZ f Q2
•
CALL
WOPM
;D = 0
9
LD
JP
BC f 1C00H
•
t
•
t
013FH
no 9TR t wn
: PATCH BACK
DOSTR :
CALL
OR
JR
u\j o 1 a no
7FC3H
A
••GET REAL ADDR •
A
Z,PRETX
; LEN=0
CALL
STORE
; A=LEN
PRETX:
POP
HL
LD
A, (HL)
SUB
9 • I
•
;MUSIC •••••";
INC
HL
RET
Z
DEC
HL
;BACK HL
PRETXX
: LD
BC,(HEAD0)
XOR
A
OUT
(C) f A #
••SET END MARK
INC
BC
LD
LD
RET
(HEAD0) f BC
(HEAD) f BC
••COPY
STORE :
STORE 1
SLOOP :
LD
LD
OR
SBC
JR
LD
OUT
INC
LD
LD
BC,(HEAD0)
HL,(HEAD)
A
HL f BC
NZ,STORE1
L ••ソ
(C) f L
BC
L.A
A f (DE)
; L=LEN
7 8 c 4 8 C4DC
1772 0 3 6 3 3
9 E E E E 0 0 c 0 0 B 0 B 31911
7 1 A A A 0 B 0 0 B 0 0 F c 0 A 0 0
FDE2 111D36B1D B 6630 3 E 212 D
A E 3 3 210E2320K E 0321 F 3322 c
第 11 章 FM 音源267
(HEAD0),BC
13CH
2027H ;OUT OF MEM
4000H
4000H
4000H
C f S0
•z,+ l
NC t S0
A, , A,-,a
(C) ,A
BC
DE
;UPPER
FE
61
CP
38
06
JR
FE
7B
CP
30
02
JR
C6
E0
ADD
ED
79
S0 :
OUT
03
13
•
INC
INC
78
t
LD
B1
OR
28
08
JR
2D
DEC
20
EA
拳
JR
ED
43 A9D6
t
LD
C9
•
RET
CD
013C
FULL :
CALL
C3
2027
•
JP
4000
TAIL :
DEFW
4000
HEAD :
DEFW
4000
HEAD0 :
DEFW
F3
ED 73 AA30
31 AA30
F5
C5
D5
E5
21 AEA8
06 0B
AF
B6
23
20 4A
10 FA
I EXEC
DI
LD
LD
PUSH
PUSH
PUSH
PUSH
LD
LD
IE0 :
XOR
OR
INC
JR
DJNZ
(INTSP),SP
SP,INTSP
AF
BC
DE
HL
HL f ACTF
B,11
A
(HL)
HL
NZ f IE1
IE0
••SOMTHING ALIVE
••NEXT BLOCK OR END
ED 4B A9D2
2A A9D4
2B
B7
ED 42
28 51
IEQ:
LD
LD
DEC
OR
SBC
JR
BC f (TAIL)
HL f (HEAD)
HL
A
HL 9 BC
Z,IE9 ;EMPTY
-> NOTHING
ED 78
03
28 0C
;NEXT BLOCK AND SET PCS
IN A f (C)
INC BC
JR Z,START
ED 78
03
20 FB
0B
ED 43 A9D2
18 E6
DROP :
IN
INC
JR
DEC
LD
JR
A f (C)
BC
NZ f DROP
BC
(TAIL) f BC
IEQ
A9B2
A9B4
A9B6
A9B8
A9BA
A9BC
A9BE
A9BF
A9C0
A9C1
A9C2
A9C4
A9C5
A9C7
A9CB
A9CC
A9CF
A9D2
A9D4
A9D6
A9D8
A9DB
A9DD
A9DF
A9E1
A9E3
A9E5
A9E7
A9EA
A9EC
A9EE
A9F1
A9F3
A9F4
AA30
AA32
AA33
AA37
AA3A
AA3B
AA3C
AA3D
AA3E
AA41
AA43
AA44
AA45
AA46
AA48
AA4A
AA4E
AA51
AA52
AA53
AA55
AA57
AA59
AA5A
AA5C
AA5E
AA5F
AA61
AA62
AA66
7791989779 E9
0270757 0C7A7
1EDEDED1EDAD9
03E3E3E03E3EC
262 試験に出る XI
0000
AEA8
AAB3
0B
F0
7B AA30
4D
E5
D5
F2 AACA
CD ADEO
78
B1
D1
E5
CC ACDB
El
7C
B5
El
C0
36 01
C9
CB 23
21 AEB3
19
4E
23
ED 43 A9D2
21 AEA8
E5
21 AEB3
16 00
ED 78
28 05
03
FE 3A
20 F7
B7
28 02
3E 01
E3
77
23
E3
71
23
70
23
14
7A
FE 0B
38 E4
El
AA68
AA6C
AA6F
AA70
AA73
AA75
AA77
AA79
AA7A
AA7C
AA7E
AA7F
AA81
AA83
AA84
AA85
AA86
AA87
AA88
AA89
AA8A
AA8B
AA8C
AA8D
AA8F
AA91
AA92
AA95
AA98
AA99
AA9A
AA9B
AA9C
AA9F
AAA0
AAAI
AAA2
AAA3
AAA4
AAA6
AAA8
AAA9
AAAA
AAAB
AAAC
AAB0
AAB1
AAB3
AAB4
AAB5
AAB8
AABB
AABC
AABD
AABE
AABF
AAC2
AAC3
AAC4
AAC5
AAC6
AAC7
AAC9
AACA
AACC
AACF
AAD0
AAD1
START :
LD
LD
(TAIL) f BC
HL,ACTF
PUSH
HL
LD
H い PC
LD
D f 0
SPC0 :
IN
A f (C)
JR
Z f SPCl ;
INC
BC
•
CP
JR
i • t
•
NZ.SPC0
SPC1 :
OR
A
JR
Z f SPC2
LD
A f 1
SPC2 :
EX
(SP) ,HL
LD
(HL) f A ;
INC
EX
LD
HL ;
(SP) t HL
(HL) f C
INC
HL
LD
(HL) f B
INC
HL
INC
D
LD
A f D
CP
ii ;
JR
C.SPC0
POP
HL ;
INC ACTF ADDR
CHECK COUNTER
DROP ACTF
;PCS ARE READY
; 00H=DEAD t 01H=ALIVE f 80H=ACTIVE
IE1 : LD DE 9 0 •〖CHANNEL
LD HL f ACTF
I EL: PUSH DE
PUSH HL
LD A f (HL)
OR A
CALL NZ f ACT ;ALIVE OR ACTIVE
POP HL
POP DE
INC H し
INC E
LD A f E
CP 11
JR NZ f IEL
IE9:
POP
POP
POP
POP
LD
El
RETI
HL
DE
BC
AF
SP f
INTSP)
: RET FROM INT
SUB
ACT :
PUSH
HL
• SAVE
ACTF
PUSH
DE
;SAVE
CH NO.
jp
P.ACT7
CALL
RCTR
••READ
COUNTER
E f HL =
URA
LD
A 9 B
OR
C
POP
DE
PUSH
HL
CALL
Z f KEYOFF
POP
HL
LD
OR
A f H
L
POP
HL
RET
NZ
LD
(HL),1
••SLEEP
RET
••ALIVE AND NOT-ACTIVE
^CT7 : SLA E
LD HL f PC
ADD HL f DE
LD C f (HL)
IMC HL
;DE = DE 拿 2
1155 E 7411
12DE7BCED
3 c B E 0 1111 DBD
2 1 7 F 2 E D c F E F E
第 11 章 FM 音源 26 J
BC
DE
KEYON
DE
BC
DONUM
A f 1
A
A f A
A f (C)
BC
: NEW BC
;NZ•NC
••SAVE NOTE
: NOMAL NOTE
RN0
RN1
RN2
PUSH
PUSH
CALL
POP
POP
CALL
LD
OR
RET
;GET A-G
GETNT: SUB
ADD
LD
IN
INC
CP
RET
INC
INC
CP
RET
CP
RET
DEC
DEC
RET
L=CODE f
4, U
W 料^)只分④
AB1A
ABIC
AB1D
ABIE
AB20
AB21
AB23
AB24
AB25
AB26
AB28
AB29
AB2B
AB2C
AB2D
AB2E
LD B, (HU ;GET PC
IN
A f (C)
••READ NOTE
JR
Z f DIE
CP
» • »
•
JR
NZ.WAKE
••HIT NOTE
DIE :
POP
DE
DIE2 :
LD
(HL) ,B
DEC
HI
#
LD
(HL) ,C
••SAVE PC
•
POP
HL
;GET ACTF
LD
(HL) ,0
••KILL (ACTF)
•
RET
••WAKE
UP
WAKE :
POP
DE
; DE=CHANNEL NO.
WUL :
IN
A, (C)
JR
Z.DIE2
CP
f • •
JR
Z.DIE2
PUSH
DE
PUSH
HL
;SAVE PC.ADDR.
CALL
DONOTE
;DO NOTE
POP
HL
JR
Z f DIE
••HIT 1 f OR 00H
POP
DE
••GET CH NO.
•
JR
C, WUL
••NOT REAL NOTE
: HIT
REAL NOTE
; A-G f N,W
LD
(HL) ,B
DEC
HL
•
LD
(HU .C
; SAVE/PC
t
POP
HL
••GET ACTF. ADDR
LD
(HL) f 80H ;MAKE ACTIVE
•
1
籲 ••
RET
DO NOTE
會 mm ^ mm
; DE=CHANNEL NO.
(BREAK
OK)
DONOTE : IN
A t (C)
INC
BC
CP
1 A 1
JR
C f DN0
;?<A
CP
•G,+ l
•
JR
NC,DN1
;?>G
t
CALL
■
GETNT
: GET A-G
AAD2
46
AAD3
ED
78
AAD5
28
04
AAD7
FE
3A
AAD9
20
08
AADB
D1
AADC
70
AADD
2B
AADE
71
AADF
El
AAE0
36
00
AAE2
C9
AAE3
D1
AAE4
ED
78
AAE6
28
F4
AAE8
FE
3A
AAEA
28
F0
AAEC
D5
AAED
E5
AAEE
CD
AAFE
AAF1
El
AAF2
28
E7
AAF4
D1
AAF5
38
ED
AAF7
70
AAF8
AAF9
2B
AAFA
El
AAFB
36 80
AAFD
C9
AAFE
ED
78
AB00
03
AB01
FE
41
AB03
38
2A
AB05
FE
48
AB07
30
34
AB09
CD
AB1A
AB0C
ABOD
C5
D5
AB0E
CD
AC6 7
AB11
AB12
D1
Cl
AB13
CD
ACED
AB16
3E
01
AB18
AB19
B7
C9
z L L t z f z
Be
8 D
7 2
B
3
2
67FD3E8CCE8E8DB9
D86E0FC22FCFC20C
264 拭験に出る XI
AD90
3F
60
3A
FE 3E
CA AC21
FE 3C
CA AC21
7F
B7
37
C9
FE 4E
28 51
FE 52
28 CE
FE 49
CA AEF5
FE 59
CA ABF3
FE 57
CA ABDD
FE 54
CA AC33
21 0000
FE 4F
28 OF
2C
FE 56
28 0A
2C
FE 51
28 05
2C
FE 4C
20 CA
E5
CD AEOE
D1
19
E5
F5
CD AD90
30 04
FI
D1
18 B9
AB2F
AB31
AB34
AB36
AB39
AB3A
AB3B
AB3C
AB3D
AB3F
AB41
AB43
AB45
AB47
AB4A
AB4C
AB4F
AB51
AB54
AB56
AB59
AB5C
AB5E
AB60
AB61
AB63
AB65
AB66
AB68
AB6A
AB6B
AB6D
AB6F
AB70
AB73
AB74
AB75
AB76
AB77
AB7A
AB7C
AB7D
AB7E
AB80
AB81
AB82
AB83
AB84
AB85
AB87
AB89
AB8A
AB8C
AB8E
AB90
AB92
AB93
AB96
AB98
AB99
AB9B
DN0 :
ACT8 :
CP
JP
CP
jp
LD
OR
SCF
RET
Z f UPDOWN
1 < f
Z f UPDOWN
; OCT UP
;OCT DOWN
A f A
A
: NZ f C
R f N f Q f L f T f O f V f I f Y f W
DN1 : CP 1 N f ;NOTE BY CODE
JR Z f NPLAY
SETGO :
CP
JR
CP
JP
CP
JP
CP
JP
CP
JP
LD
CP
JR
INC
CP
JR
INC
CP
JR
INC
CP
JR
PUSH
CALL
POP
ADD
PUSH
PUSH
CALL
JR
POP
POP
JR
f R f
Z f RNl ;Rn
••GAKKI BANGOU
Z f INST0
f Y f ; 0-7 : OPM f 8-10:FSG
Z f WREG
1 W 1
Z f WAIT
••BIG OMOTE f SMALL URA
•T 1 ;TEMPO
Z f STRUN ;RUNTIME SET TEMPO
HL.e
• 0 ,
Z,SETGO
L
f V f
Z,SETGO
L
f Q f ;RATIO
Z,SETGO
L
1 L f ;DEFAULT LEN
NZ f ACT8 ;NEXT
HL
DFLTBL
DE
HL 9 DE
HL
AF
NUMBER
NC f STGl
AF
DE
ACT8
STG1 :
LD
POP
POP
EX
LD
CP
JR
LD
CP
JR
SET
JR
H f A
AF
DE
DE f HL
(HL) t E
••SAVE LAST
ACT8 ;RET WITH C,NZ
NZ
A t D
f 0
NZ f ACT 8
7 f (HL)
ACT8
SET BIT7
NPLAY : PUSH
CALL
JR
LD
CP
JR
DE
NUMBER
C f NPLAY9
A f L
96
NC f NPLAY9
; A=A MOD 12•
B=A/12
LD
E t 0
NPL :
SUB
12
JR
C f NPLAY0
INC
E
JR
NPL
NPLAY0 :
ADD
A f 12 + 5
5 D 8 D E 0
D c 3 7 F 3
0 c 3 91
0 0 0 FI
E 6 8 c 8 6
1 D 3 11 c
D F 1 3 4 6
9 9 A A A A
B B CQ CQBCQ
A A A A A A
c 0 2 B E 7
4 B 0 A F A
711B3E0AE0B8
6FDE7F27F2C1
第 11 章 FM 音源:? 65
ACED
ADE0
FFFF
ADFC
AB16
D5
CD AD90
38 24
ED 78
FE 2C
20 1R
03
E5
CD AD90
7D
El
3815
D1
FE 0A
38 07
3C
FE 0F
38 02
D6 0E
57
1C
EB
D1
D5
E5
CD AE0E
22 ABDB
D1
7E
73
6A
D1
F5
C5
D5
CD AC67
D1
Cl
CD ACED
FI
2A ABDB
77
C3 AB16
D1
C3 AB39
ABA8
ABAA
ABAC
ABAD
ABAF
ABB1
ABB3
ABB4
ABB5
ABB6
ABB7
ABB8
ABB9
ABBC
ABBF
ABC0
ABCl
ABC2
ABC3
ABC4
ABC5
ABC6
ABC7
ABCA
ABCB
ABCC
ABCF
ABD0
ABD3
ABD4
ABD7
ABD8
ABDB
ABDD
ABDE
ABE1
ABE2
ABE3
ABE4
ABH7
ABE8
ABEB
ABEE
ABEF
ABF0
ABF3
ABF4
ABF7
ABF9
ABFB
ABFD
ABFF
AC00
AC01
AC04
AC05
AC06
AC08
AC09
AC0A
AC0B
AC0C
AC0E
AC0F
AC11
ACM
AC15
AC18
AC IB
ACID
AC IE
CP
JR
INC
CP
JR
SUB
NPLAY1 : LD
LD
LD
; HL=CH NO.
LD
POP
PUSH
PUSH
PUSH
CALL
POP
POP
CALL
POP
LD
LD
JP
10
C f NPLAYl
A
15
C. NPLAYl
14
D, A
INC
E
; D=CODE f E=OCT
EX
DE f HL
POP
DE
PUSH
DE
• PUSH
CH
PUSH
HL
••PUSH
CODE,OCT
CALL
DFLTBL
LD
(NPLAYW)
,HL
POP
DE
A, (HU
(HL) f E
;PICK OCT
;SET OCT
L t D
DE
AF
BC
DE
KEYON
DE
BC
DONUM
AF
HL,(NPLAYW)
(HU ,A ;BACK OCT
RN2
NPLAY9 : POP
JP
DE
ACT8
NPLAYW :
WAIT :
DS
WREG :
PUSH
DE
CALL
DONUM
POP
DE
PUSH
DE
PUSH
BC
CALL
RCTR
INC
HL
LD
BC f 0FFFFH
CALL
WCTR
POP
POP
BC
DE
JP
RN2
PUSH
DE
CALL
NUMBER
JR
C f WREG9
IN
A f (C) %
CP
9 t
f
JR
NZ f WREG9
INC
BC
PUSH
HL ;
CALL
NUMBER
LD
A t L
POP
HL
JR
C,WREG9
POP
DE
=REG NO. f A=DATA f E=CHANNEL
PUSH
BC
LD
D f A
LD
A f E
CP
8
LD
A f L
JR
C f WROPM
CALL
WPSG
POP
BC
JP
ACT8
;DATA
;WRITE REGISTER (OPM)
WROPM : CALL WOPM
JR WREG1
WREG9: POP
JP
DE
ACT8
5D155D31D113
DCDDCC20CCDC
3 9
c 3
5
D
9
3
8 7 D B
0 0 A A
57BED8D13
C57F73CCC
D 7 B
A F A
D 8 13
cl DC
試験に出る XI
00
0E4E
0000
10
23
12
6A
42
02
STR1
STR2
EF
LD
LD
LD
LD
LD
SLA
RL
ADC
OR
SBC
JR
ADD
DEC
INC
DEC
JR
C f L
B f 0
DE f 3662
HL f 0
A,16
E
D
HL,HL
A
HL f BC
NC f STR2
HL f BC
E
E
A
NZ f STRl
••BACK
AC5C
7B
AC5D
32
AE17
AC60
CD
A9E7
AC63
Cl
AC64
C3
AB39
AC67
7B
AC68
FE
08
AC6A
38
3A
AC6C
AC6D
7D
D5
AC6E
CD
AE0E
AC71
46
AC7 2
23
AC73
4E
AC74
87
AC75
5F
AC76
21
AE18
AC79
19
AC7A
56
AC7B
23
AC7C
5E
AC7D
CB
3B
AC7F
CB
1A
AC81
10
FA
AC83
AC84
El
61
AC85
AC86
AC88
AC89
AC8C
AC8D
AC8E
AC91
AC92
AC93
7D
D6 08
87
CD ADC3
3C
53
CD ADC3
7D
54
CD ADC3
LD
LD
CALL
A,E
(TMPV) f A
TOCTC1
KEYON :
PSGDO
PSG1 :
: FREQ
VOL
POP
BC
JP
ACT8
< A-•A ,
A+,.G
•G+>:0-14
LD
A f E
•.CHANNEL NO.
CP
8
JR
C f OPMDO
LD
PUSH
A,L
DE
; A=CODE
CALL
DFLTBL
LD
B f (HL)
;GET OCT
INC
HL
LD
C f (HL)
;VOL
ADD
A, A
LD
LD
E,A
;D = 0
HL f PSGFRQ
ADD
HL f DE
LD
D f (HL)
INC
HL
LD
E f (HL)
; ED=FREQ
SRL
E
RR
D
; DE=DE/2
DJNZ
PSGl
POP
HL
H f C
し :: CHANNEL NO.
LD
••SAVE VOL
LD
A t L
SUB
8
; A=FREQ LOW
ADD
A, A
CALL
WPSG
INC
LD
A
D,E
; A=FREQ HIGH
CALL
WPSG
;SET FREQ
LD
LD
A,L
; CH8 -> R8
D f H
;D = VOL
CALL
WPSG
TONE?
UPDOWN
SUB
CALL
ADD
JP
CP
JP
LD
JP
DFLTBL
A f (HL)
Z f ACT8
9
NC f ACT8
(HL) f A
ACT8
;TEMPO
STRUN:
CALL
JP
LD
CP
JP
PUSH
NUMBER
C f ACT8
A.L
30
C f ACT8
BC
;TOO SMALL
AC40
AC41
AC4 3
AC46
AC49
AC4B
AC4D
AC4F
AC51
AC52
AC54
AC56
AC57
AC58
AC59
AC5A
AC21
AC23
AC26
AC27
AC2A
AC2C
AC2F
AC30
AC33 CD AD90
AC36 DA AB39
AC39 7D
AC3A FE IE
AC3C DA AB39
AC3F C5
D611EBBD7D09DCD0
40123 CCEBE 301132
E 9 9 9
0 3 3 3
D E B 9 B B
3 A A 0 A A
6
D
CD 86 CAFED277C3
第 11 章 FM 音源267
AD02
AD04
AD07
AD08
AD09
AD0A
AD0B
AD0C
AD0D
AC96
AC98
AC9A
AC9D
AC9F
ACA2
ACA5
3E 07
16 F8
CD ADC3
3E 0D
CD ADCC
CD ADC3
C9
ACA6
ACA7
ACA9
ACAB
ACAD
ACAF
ACB1
ACB3
ACB5
ACB7
ACB8
ACB9
ACBC
ACBD
ACC0
ACC1
ACC2
ACC3
ACC4
ACC5
ACC6
ACC7
ACC8
ACC9
ACCA
ACCB
ACCC
ACCE
ACD1
ACD2
ACD4
ACD5
ACD7
ACDA
7D
C617
FE IB
38 0B
D610
FE 0F
38 05
FE 12
28 01
3C
D5
CD AF52
F5
CD AE0E
7E
3D
87
87
87
87
57
FI
82
57
El
7D
C6 28
CD ADD5
7D
F6 78
57
3E 08
CD ADD5
C9
ACDB
ACDC
ACDE
7B
FE 08
38 06
ACE0
ACE2
ACE5
16 00
CD ADC3
C9
ACE6
ACE7
ACB9
ACEC
53
3E 08
CD ADD5
C9
ACED
ACEE
D5
CD AD04
ACF1
ACF2
ACF3
ACF7
ACF8
ACF9
ACFD
AD00
AD01
2B
IB
ED 53 AD02
D1
C5
ED 4B AD02
CD ADFC
Cl
C9
E
0
E
A
D3363E5D
c 22525 DE
268 試験に出る XI
CP
JR NZ f DONOML
;DIRECT COUNTER SITEI
INC BC
LD DE,0
XNUM0
XNUMZ
XNUML
CALL
JR
LD
JR
LD
CALL
JR
LD
LD
ADD
ADD
ADD
ADD
LD
LD
ADD
EX
JR
DIGIT
NC f XNUMZ
DE f 1
XXX
E,A
DIGIT
C f XXX
H f D
L f E
HL.HL
HL.HL
HL f DE
HL.HL
E f A
D f 0
HL,DE
DB f HL
XNUML
; D=0
DONOML : CALL
JR
;USE DEFAULT VALUE
LD L t E
BIT 7
JR Z
; 1 • 1 =FUTBN !
RES 7
LD A
NUMBER ;
NC,DONUM0
L
DO
NUM0
L
0FEH
; BIT7 = 0
DNOK :
XXX :
DONUM 1 :
;KKKK
PUSH
AF
LD
A f L
CP
33
JR
C f DNOK
LD
L f 32
•MAX 32
POP
AF
LD
SLA
L
: HL=HL#2
LD
DE f LENTBL
ADD
HL f DE
LD
E f (HL)
INC
HL
LD
D,(HL)
; DE=REAL LEN
CP
0FEH
JR
NZ f DONUM1
LD
H,D
LD
L t E
SRL
D
RR
B
; DE=DE/2
ADD
HL 9 DE
; HL=HLtl.5
EX
DE.HL
LD
H,D
; DE=URA CTR
LD
L f E
;COPY
POP
AF
; A<-D=Q
PUSH
LD
IN
HL
H f A
A f (C)
DONUM2 :
CP
LD
A t H
POP
HL
JR
NZ.DONUM2
INC
BC
IN
A f (C)
CP
JR
NZ f DONUM4
INC
LD
JR
BC
HL f 0FFFFH
DONUM4
DEC
A
JR
Z f DONUM3
HL f DE
ADD
JR
DONUM2
CD AD90
30 09
6B
CB 7D
28 04
FE 40
20 21
03
11 0000
CD ADBO
30 05
11 0001
18 41
5F
AD0F
ADI1
AD13
AD14
ADI"
AD1A
AD1C
AD1F
AD21
AD22
AD25
AD27
AD28
AD29
AD2A
AD2B
AD2C
AD2D
AD2E
AD30
AD31
AD32
AD34
AD37
AD39
AD3A
AD3C
AD3E
AD40
AD42
AD43
AD44
AD46
AD48
AD4A
AD4B
AD4D
AD4F
AD52
AD53
AD54
AD55
AD56
AD58
AD5A
AD5B
AD5C
AD5E
AD60
AD61
AD62
AD62
AD63
AD64
AD65
AD66
AD67
AD69
AD6B
AD6C
AD6D
AD6F
AD70
AD72
AD74
AD76
AD77
AD7A
AD7C
AD7D
AD7F
AD80
E 8 A B
F 0 31
F
F
6
3
DE 12 0 0 5 E
B F 2 0 2 0 2 A
BE5DE8E16B19E36 E02BBB9B 2 B 1 5 7 D E c 1 0 3DE 0318 D 8 9 8
C3F7F32F2C11525 F266CC1E 6 6 F E6EF7E2 0EF 2021 3 2 11
8 6 D 8B8F2 3 A
7 2 0 7 21 FI 0 F
0
B
D B
A3
0
0
E
E
D82B9999F69B8
c 36622125 11E1
第 11 章 FM 音源 269
;ERR
: SAVE
NUM0 :
IKINARI
NUML
CALL
RET
9 t
•
LD
CALL
JR
LD
LD
ADD
ADD
ADD
ADD
ADD
LD
JR
DIGIT
C
MO ERROR
L f A
DIGIT
C.NUM1
H
A
A
A
A
A
A
A
A
A
L
A
H
A
NUML
NUM1 : OR
RET
NUM9 : SCF
RET
DIGIT : IN
CP
JR
SCF
RET
DIGIT1 : SUB
INC
RET
CP
JR
• DEC
DIGIT2 : SCF
RET
WPSG : LD
OUT
DEC
% OUT
RET
RPSG : LD
OUT
DEC
IN
RET
WOPM : PUSH
LD
OUT
INC
OUT
POP
RET
RCTR : PUSH
SLA
SLA
LD
ADD
A ;NC
A f (C)
C f DIGIT1
t 0 ,
BC
NC
f • f - f 0 f
Z f DIGIT2
BC
BC f 1C00H
(C) t A
B
(C) t D
BC,1C00H
(C) f A
B
D f (C)
BC
BC f 0700H
(C) f A
C
(C) f D
BC
DE
E
E
HL f PACK
HL f DE
DONUM3 : SRL
RR
SRL
RR
SRL
RR
#
t
; HL=OMOTE->BC f DE=URA->HL
DONUM4 : EX DE f HL
RET
;RETURN HL=URA f DE=OMOTE
t
;L=VALUE,Carry = NOTHING,BC = AUTO INC
••LAST ジノ THEN Acc = FEH
NUMBER : IN A,(C>
JR Z,NUM9 ;HIT END
CP 1 : 1
JR Z.NUM9 : HIT END
CB 3C
CB ID
CB 3C
CB ID
CB 3C
CB ID
EB
C9
ED 78
281A
FE 3A
2816
CD ADB0
D8
6F
CD ADB0
38 0A
67
7D
87
87
85
87
84
6F
18 FI
AD82
AD84
AD86
AD88
AD8A
AD8C
AD8E
AD8F
AD90
AD92
AD94
AD96
AD98
AD9B
AD9C
AD9D
ADA0
ADA2
ADA3
ADA4
ADA5
ADA6
ADA7
ADA8
ADA9
ADAA
ADAC
ADAD
ADAE
ADAF
ADB0
ADB2
ADB4
ADB6
ADB7
ADB8
ADBA
ADBB
ADBC
ADBE
ADC0
ADC1
ADC2
ADC3
ADC6
ADC8
ADC9
ADCB
ADCC
ADCF
ADD1
ADD2
ADD4
ADD5
ADD6
ADD9
ADDB
ADDC
ADDE
ADDF
ADE0
ADE1
ADE3
ADE5
ADfc8
0
2 4 5 1
0
c 9 1
17 5
V%
0
c 9 0
17 5
0
7 9 1
0 7 5
c
3 3 E
2 2 A
8 A 2 0 El
7 3 0 3 F 0
79 79 DE 879630 E8B79 1D5D9 1D5D9 5 1 D c D 1 9 5 BB 19
BC 3C EF33CD0DF203C 0 E 0 E c 0 E 0 E c c 0 E 0 E c c D c c 2 1
試験に出る XI
ADFC
23
23
AEC9
AE7C
23
23
12D0
11C2
10C4
0FD2
0EEE
1DDE
1C2E
1A9A
191C
17B4
165E
165E
151E
13EE
12D0
0800 0400
0200 0155
0100
00CC 00AA
0092 0080
0071
0066 005D
0055 004E
0049
0044 0040
003C 0038
0035
0033 0030
002E 0020
002A
0028 0027
0025 0024
0023
0022 0021
0020
ADE9
ADKA
ADEB
ADEC
ADED
ADEE
ADEF
ADF0
ADF1
ADF2
ADF3
ADF4
ADF5
ADF6
ADF9
ADFA
ADFB
ADFC
ADFE
AE00
AE01
AE04
AE05
AE06
AE07
AE08
AE09
AE0A
AE0B
AE0C
AE0D
AE0E
AE11
AE13
AE15
AE16
AE17
LD
INC
LD
INC
LD
INC
LD
EX
DEC
DEC
POP
PUSH
PUSH
CALL
POP
POP
RET
C t (HL)
HL
B f (HL)
HL
E f (HL)
HL
D f (HL)
DE f HL
BC
HL
DE
BC
HL
WCTR
BC=OMOTE
DE=URA
HL=URA
HL
BC
WCTR :
SLA
SLA
PUSH
LD
ADD
LD
INC
LD
INC
POP
LD
INC
LD
RET
E
E
HL
HL t PACK
HL,DE
(HL) f C
HL
(HL) f B
HL
BC
(HL) f C
HL
(HL) f B
BC=OMOTE
BC=URA
DFLTBL
LD
SLA
SLA
ADD
RET
HL t DFLW
E
E
HL f DE
VAR AREA
TMPV :
DS
1
PSGFRQ :
DW
12D0H
Ab = G#
DW
11C2H
A
DW
10C4H
A 參
DW
0FD2H
B
DW
0EEEH
B#=(C)
DW
1DDEH
C
DW
1C2EH
C#
DW
1A9AH
D
DW
191CH
D#
DW
17B4H
E
DW
165EH
E# = F
DW
165EH
F
DW
151EH
F#
DW
13EEH
G
•
DW
12D0H
G#
LENTBL :
DW
2048,1024,512,341, 256
DW
204 , 170,146, 128,113
DW
102,93 ,85,78,73
DW
68,64,60,
56,53
DW
51,48,46,44,42
DW
40,39,37,
36,35
DW
34 f 33,32
OCT f VOL f Q f LEN :: 4. 100( 12).8.4
E363E36BBB155D119 BB 519130311309 1 B B 9 9
4242525 E02DCECECC CCE 217272 C727C 2 c c 1 c
8ACE 02468 ACE024 6AE048AE248CE268C026
111122222222333 333444445
eeeeeeeeep^eseee
AAAAAAAAAAAAAAA
55556666777
EEEEEEEEEEEEEEEEEEEE
AAAAAAAAAAAAAAAAAAAA
第 11 章 FM 音源 277
ACTF : DS
PC : DS
PACK : DS
08
AB39
AD90
48
; DATA=B000H-B72FH (10t40+36t40)
INST0 : LD A,E
CP 8
JP NC f ACT8 ;PSG
PUSH DE ;SAVE CH NO
CALL NUMBER
JR C f INST9
DEC L ; L=L-1
LD A f L
CP 40
JR NC f INST9
AFEC
POP
PUSH
LD
ADD
LD
DE
DE
HL f INSTN
HL t DE
(HL) 9 A : SAVE INSTN
AF2F
11 0005
LD
DE f 5
AF32
19
ADD
HL f DE
••HL=HL+5
AF33
3E 18
LD
A f 18H
AF35
CD AF4D
CALL
WOPMX
;LFRQ
AF38
3C
INC
A
: A=19H
AF39
CD AF4D
CALL
WOPMX
;PMD
AF3C
CD AF4D
CALL
WOPMX
;AMD
AF3F
3E IB
LD
A f 1BH
AF4 1
CD AF4D
CALL
WOPMX
;FRM
AF44
El
POP
HL
BC
AF45
Cl
POP
AF46
C3 AB39
•
JP
ACT8
AF49
D1
INST9 :
POP
DE
;DROP
AF4A
C3 AB39
•
JP
ACT8
AMD
56
WOPMX :
LD
D,(HL)
AF4E
23
INC
HL
AF4F
C3 ADD5
•
jp
WOPM
AF52
F5
OPMV0 :
PUSH
AF
; A=CODE
AF53
D5
PUSH
DE
; DE=CH NO
2 試験に出る XI
6F LD L f A
CD AFC8 CALL GETVTD
AE78
AE7C
AE80
AE84
AE88
AE8C
AE90
AE94
AE98
AE9C
AEA0
AEA4
AEA8
AEB3
AEC9
AEF5
AEF6
AEF8
AEFB
AEFC
AEFF
AF01
AF02
AF03
AF05
AF07
AF08
AF09
AF0C
AF0D
AF0E
AF0F
AF12
AF13
AF14
AF15
AF17
AF18
AF1B
AF1D
AF1F
AF22
AF24
AF27
AF29
AF2C
AF2D
DFLDMY : DB
DFLW : DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
4 , 100 , 8,4
4 f 100 f 8 f 4
4 •100,8,4
4 f 100, 8,4
4,100,8,4
4 f 100,8, 4
4 f 100 f 8 f 4
4 f 100 f 8 f 4
4 •100,8,4
4,12 f 8 f 4
4 f 12 f 8 f 4
4,12 f 8 f 4
B E 2 5
7 F D D
D 8 D D E 0
c 3 2 7 F 3
15 19 7
D D 2 1 7
155E3D66D6D
DCE38CC1CCC
E D D 0
1 c 12
444444444444
000000000000
8 8 00 00 00 8 00 00 00 00 00 8
000000000000
444444444 ccc
666666666000
444444444444
000000000000
0
01234567891
9 2 0
0 0 8
B 0 6 2 3 3 0
c 3 F 1 2 11
4 4 F 1 9
F 0 7 0 F
0 6 B B E E 8 E B 0
1 0 E 2 3 B 3 7 21
MML
2 4
D D D D D D D T
DSLDADADLDLDADADADADLDADRE
0
9
0 1
0 B
6994D 9999199
22255222 111c
143AAAAAAABD1B9E
1551111 111EC027 A
210AAAAAAA5419D8
242111 1111E52AE7
DECAAAAAAA56C6F1
24411111 11A34DA2
395AAAAAAABD02DE
EC 411111 11DC224A
2E94AAAAAAA 25947
224511111137 B A 41
93E4AAAAAAF8C492
A1 45111111727 DA3
0219 AAAAAA13B22E
024411 1111D052D1
1E84AAAAAADEF02E
22451111 11CFA 423
0808080808080808
BBCCDDEKFF 001122
8888888888999999
D65F7B 29007 D 7258
F 8177 CF90B5DCE12
0D011EEDD31B3DD3
BE1 2053 CACE44EE0
D031C2785D9DD979
E 0203200 DCAEECB6
080CDA7ED1FB399D
0003CA03C0920AAE
41621217 AFD8944A
20330300 F3CC7DD3
1BB3D1 960333 D3AE
020C32C12C02E 422
EC6E 29195 C8BFD95
A0032AE 71123 AEA0
C6B398BDD 0769960
73EFADFEA0BDAAD2
130B4D0351FE66B2
12BF6C00D077DD44
0 8 0 8 0 s 0 8 0 8 o 8 0 8 0 8
33445566778899 AA
9999999999999999
A A A A. . .
F4D8754A79D100A0
9575016 c 833000 CB
B3D30E17E 46000 AE
71EC 4301445000 CB
E3A1099A99D 00003
FOE 007734040000 c
690C0DD99A 000000
07234 EE 700500000
8DDD078DADF 30000
3E2C025E 00400000
10890 EE7959F0000
6E0C433CC40F0000
E 689079 E94A 30000
FC2A 007374500000
A 21604 D7D9EA0009
10BD20E0E04C000D
F0 837117 E3A 20006
63742000 A 4430005
B7 1B07F 75625 D146
91BB23A 023184 FAA
18A4D 0658818 E10A
3A4DE2EE2273AEFA
A10A138E873B8A00
A 22250 1A7BE0AA23
05398898 D73E13BB
3E2A27AAEF2F2B07
35622 D 21007 A04ED
7DBD4ED 202770 CFE
D5FBDC396A3407B1
ECA4E04A13E10B7F
35BD78D2EE131EC1
FF0EB2EDAF02171C
4A6AB3B333E 01531
0A0F2004B037EE2D
90E098BD1 5234511
33A1A7FE2002EDDE
AC30
AC38
AC40
AC48
AC50
AC58
AC60
AC68
AC70
AC78
AC80
AC88
AB30
AB38
AB40
AB48
AB50
AB58
AB60
AB68
AB70
AB78
AB80
AB88
AB90
AB98
ABA0
ABA8
SUM : AF
ACB0 0F
ACB8 D5
ACC0 7E
ACC8 82
ACD0 AD
ACD8 D5
ACE0 16
ACE8 08
ACF0 AD
ACF8 C5
AD00 Cl
AD08 23
AD10 40
AD18 B0
AD20 41
AD28 6B
SUM : BB 5E 36 40 EB 04 90 C3
SUM : 9A 72 30 1913 2D 68 B7
SUM : BA 42 CC D3 51 E6 62 5B
ADB0 ED 78 FE 3A 38 02 37 C9
ADB8 D6 30 03 D0 FE FE 28 01
ADC0 0B 37 C9 01 00 1C ED 79
ADC8 05 ED 51 C9 01 00 1C ED
ADD0 79 05 ED 50 C9 C5 01 00
ADD8 07 ED 79 0C ED 51 Cl C9
ADE0 D5 CB 23 CB 23 21 C9 AE
ADE819 4E 23 46 23 5E 23 56
ADF0 EB 0B 2B D1 C5 E5 CD FC
ADF8 AD El Cl C9 CB 23 CB 23
AE00 E5 21 C9 AE 19 7123 70
AE08 23 Cl7123 70 C9 217C
AE10 AE CB 23 CB 2319 C9 33
AE18 D0 12 C211 C410 D2 0F
AE20 EE 0E DE ID 2E 1C 9A 1A
AE28 1C 19 B417 5E 16 5E 16
SUM : 9A F0 A417 6C 3B F7 8B 113D
AAB0
AAB8
AAC0
AAC8
AAD0
AAD8
AAE0
AAE8
AAF0
AAF8
AB00
AB08
AB10
AB18
AB20
AB28
SUM : 69 A9 64 BC BF 4E 85 7A 0F37
AE30 IE 15 EE 13 D0 12 00 08 : IE
AE38 00 04 00 02 55 01 00 01 : 5D
AE40 CC 00 AA 00 92 00 80 00 : 88
AE48 71 00 66 00 5D 00 55 00 : 89
AE50 4E 00 49 00 44 00 40 00 : IB
SUM : 761C 3F 52 B9 EA B3 AB 3973
AD30 19 EB 18 EE CD 90 AD 30 : 44
AD38 09 6B CB 7D 28 04 CB BD : 70
AD40 3E FE F5 7D FE 2138 02 : 07
AD48 2E 20 FI26 00 CB 2511 : 66
AD50 36 AE 19 5E 23 56 FE FE : D0
AD58 20 08 62 6B CB 3A CB IB : E0
AD60 19 EB 62 6B FI E5 67 ED : FB
AD68 78 FE 26 7C El20 0D 03 : 29
AD70 ED 78 FE 2B 20 18 03 21 : EA
AD78 FF FF 1812 3D 28 0319 : A9
AD80 18 FA CB 3C CB ID CB 3C : 08
AD88 CB ID CB 3C CB ID EB C9 : 8B
AD90 ED 78 281A FE 3A 2816 : ID
AD98 CD B0 AD D8 6F CD B0 AD : 9B
ADA0 38 0A 67 7D 87 87 85 87 : 40
ADA8 84 6F 18 FI B7 C9 37 C9 : 7C
AC90
AD
7D
54
CD
C3
AD
3E
07
00
AC98
16
F8
CD
C3
AD
3E
0D
CD
63
ACA0
CC
AD
CD
C3
AD
C9
7D
C6
C2
ACA8
17
FE
IB
38
0B
D6
10
FE
57
950DDEBE8B83
3C0E1A701C0C
AB1297BD1B6D
DA 2101 AC23DC
D9EB2295FBD3
A30C033D5C75
0AE30B3D7E1C
9D4237C 78563
DE1B2F1AE31D
C11C4EC342EA
BE00D 09836 A3
AF01E2A325FC
9D6E7D 78690 D
3703B3E 041 1C
3BD0ACDEEEA7
CA 4061 CFAA18
18AE3F15D90EF 618
22CF305ECB2F3D13
AE9BA8EA58CB806F
C44AC2FCF14C30C0
CEE34FC051EBDE9E
3FFF5422EDFAA1FF
E9EAEEAC 91300 A8C
FCCCFF041F 729313
C789B08E14B2D0C7
A325A02FD0E0C310
172ED06CE01E 5038
2B5FD052A3DFD603
AFEEA1E5ED1A7E8A
C7FAC2F00AF7AF30
EC157CC8D0708DCE
3A5F5A22C96B170F
CE15D6E41D3ED820
3AFDC030DA2FC160
1E7D883DDCE800B6
005C035CAFA 70031
8D78E8952DED018F
2C8230CD0C0E 0035
25767 ED93DD511D9
1F8C5FAC5ACD11A2
EF7D8B3DD20E 3509
FA 8777 CAE 02500 B1
527169 D5BBF310D9
058EFCCD1 44223 C2
8DD7DD0DBD960DF9
3C357A0C2EC52A52
7 7EE6A19A54AEFA58
6 DF 81444 C6F9496FG
2
A
F 4 7 16 8
0 c c E 0 A
A 0 5 4 F 1 3
D 4 A 8 6 c E
4
3
A78CC347B4A3CB78
EE8F 79909 F92A291
51C11D 318358 B9A7
DDCFDE2D3013A3C7
1B5CBDD1DE8D936B
DADAACACAl 373 C8A
BB5D650D 00183 1E9
EDCE1DEA92E0CDA3
C25D33DCDCDE17E2
12FCC5CFC27FCF0D
7E117 A5D5EDBD8D9
5ADC70CCDFA7A1C0
EEA1BB5FB 8073 DDE
006DAADFA795CA3F
6D3CB91F6DD5D56B
DC7AD3DF1ECCCDDA
2 5 E 7 A3C1 34517 DB9
0E 762 CA0C2ED0CA3
0808080808080808
BBCCDDEEFF 001122
BBBBBBBBBBCCCCC 3
AAAAAAAAAAAAAAAA
B
0
A 6 8 0 81
F 5 A 6 F 5
D2A41E59B8
2710 FB134C
550360150 1A 43270
5075425 D0619EF7B
AC69E14E 080718 BE
AC31FEFF 7736072 F
A50E418DDD8DEDE9
CECA072CEE4C3EFC
21138 B8589E5CFCB
FDEB227E3CFDA620
515180 D510A5D7CD
DBB277EDD82CE 822
58C3D110768BD188
E772EDDFE33AC4CC
DD1B 689881 1A16D3
4AEC40C22E41CD22
D0C9300A11ED19EE
EEAC2203E7FCDCFF
BDB1EA6EAB34C 738
FCD0433FA203AB0C
第 11 章 FM 音源 275
AEB0
AEB8
AEC0
AEC8
AED0
AED8
AEE0
AEE8
AEF0
AEF8
AF00
AF08
AF10
AF18
AF20
AF28
SUM : 8165 6A 36 59 FE 12 64
1752
61
0D
Cl
08
59
53
26
58
BA
CD
5B
5D
D3
96
37
A1
AE58 3C 00 38 00
AE60 30 00 2E 00
AE68 28 00 27 00
AE70 23 00 22 00
AE78 04 64 08 04
AE80 04 64 08 04
AE88 04 64 08 04
AE90 04 64 08 04
AE98 04 64 08 04
AEA0 04 0C 08 04
AEA8 09 4C 44 09
2C
92
04
4FD
FA
0F
F3
7B
3C
MML 访機能てあ 3
では次に MML の機能を説明する。
主な機能は MZ - 2500の BASIC などとほぼ同じであるが,若干機能を削ってある。しか
し,実害はないはずである(と突っ張る)。削られた機能のうち一番ナニなのが「連符」
276 試験に 出る XI
100 TEMPO 0
110 MUSIC ”11 V127 Q4 : I1 V127 Q4 : 1 1 V127 Q4 M
120 MUSIC "T150 04 L4 C&E&G G2>G GRE E<RC C&E&G";
130 MUSIC ":03 L4 RRR CGG CGG CGG CGG ••:
140 MUSIC ":03 L4 RRR REE REE REE REE ••
150 MUSIC •• G2>G GRF FR03B B&04D&A A2>A";
160 MUSIC M : 02B>GG< B>GG< B>GG DGG< B>GG";
170 MUSIC ":03RFF RFF RFF RFF RFF M
180 MUSIC ” ARF FR03B B&04D&A A2>A ARE";
190 MUSIC ":02B>GG く B>GG DGG CGG CGG";
200 MUSIC ” : 03RFF RFF RFF REE REE"
210 MUSIC •• ER04C C&E&G >C2>C CR<G GR04C C&E&G ”;
220 MUSIC ":03CGG CGG CGG CGG CGG CGG";
230 MUSIC ":03REE REE REE REE REE REE”
240 MUSIC •• 05C2>C CR<A ARD D&F&A A1 F#G";
250 MUSIC ":03DAA DAA ARR D&F&A <B>GG< B>GG";
260 MUSIC M : 03RFF RFF FRR RRR RFF RFF”
270 MUSIC " 06E1 C く E E2&D A24G Cl RR";
280 MUSIC ” : 03CGG CGG A2. G2. CGG CRR";
290 MUSIC ":03REE REE F2. F2. REE"
SUM : 37 5
リスト 1 卜 6
SUM
F0 F6 66 44 AF 88 F4 6E00
2B AB 7D B16B E5 2AF1
サンプル曲(美しく育きドナウ)
C9C4D7C 388 1D3DE1
4025032403 DC8C11
9A95BC19ED2F04FA
00243240 FA 4621 AF
AD33A49AB007E6D0
0045040379373142
D385D9427D8950DD
032400435 C21E1C1
3C9234C195EF568F
320544450 DFACC0A
B14B4C9ACBDC1F67
245354004 A7EDACD
395939 ADC9D1FDDD
405040004322 A4AC
44F10AD 812858 D56
544420034 D4DCCD0
C 4868888086
DB98EEEE 939
00004444443
00000000004
3A 40888888 C
32220000002
00004444 CC3
00006666004
5C 514444442
32220000004
F7296D00
7D52C410
6D099D60
EC52CCC0
F1AD90F0
7F0511A0
E1D416D0
3E05BC40
FF990FD91
AEC29ACC0
6019 1D8F1
B1F2140A0
23109 D6D1
F2D01CD40
17F698FD1
87A220AC0
DC2FACB86AE1 8063
3085A32C9BF48D28
FE93E9E8D60BBF3F
A33CA1 02008 E272A
DF33EF791F64E656
4AC20A080AF07CFB
DD16DC6B 0426103 A
C4C5CEEC2C 00098 F
8D1B51EB 71048487
1CEAD 270013 F345B
EFF955F8E990EDEE
3AA3DFA3F101BE37
9DD 3518410 B3F154
144CFDC090C17CD0
0DD1DEDEB6E3E 916
0CCD A7CFC0723FD0
5CBB53E 77142 B0F5
031 AD 2600101214 E
7 2 3 F D 0
3E 77142 B0F5
2600101214 E
0 8 0 8
3 3 4 4
F F F F
A A A A
の処理である。 MZ - 2500では,
PLAY '、 { CDE } 4 "
などとすることによって3連符 ( n 連符も可能)が使えたのであるが,こっちではこの機能
は使えない。ただしちゃんと逃げ道は用意しておいたので,連符を使いたい人は後で紹介
する別の方法を使っていただきたい。
さて機能をまとめたのが表11 -9である。一つ大事な点は,音長の指定方法である。
HuBASIC では0が32分音符,1が16分音符,……,9が全音符となっていたが,ここで
は MZ -2500 と同じく,32が32分音符,16が16分音符,……,1が全音符としてあ
る。なお MZ - 2500にはないが0は全音符の2倍の長さである。それから,「.」を付けるこ
とによって音長は 1.5 倍になる。すなわち 「 C 4.」 は符点4分音符なわけだ。
表 11-9 MML の檄能表
厂 文字 !
機 能
f C ~ G , A , B
音階
+ • s
音階を半音上げる
_
音階を半音下ける
R l
休符 (£ : 0-32)
•
音長を 1.5 倍にする
Nx
音階コード x による音の発生 ( x :0 - 95)
Qn
音の出る時間比率の設定 ( n : l 〜 8)
& (& + )
前後の音をつなぐ(タイ)•幻 !
LI
省略時の音長指定 (£ : 0-32)
Ts
テンホ指定 (S : 30-255)
On
オクターブ指定 (n : 1-8)
>
オクターブを一つ上げる
<
オクターブを一つ下ける
Vn i
音量設定 ( n : 〇〜127もしくは〇〜 15)
In
FM 音源の音色設定 (n : 1-40)
Yr , d
レジスタ r にデータ d をセット
W l 1
£の長さだけ状態を維持する (£ : 1-32)
数値の指定方法
1) XI 6 -など
2) 音長を直接カウンタ値で指定する場合に限り
• C 沿 256" など
注) C 2& + C 4 =i
C 2. などとなる
次に指摘しておくのが音階の指定方法である。 HuBASIC では「な C 」 などで半音上の音
を指定していたが,ここでは re ;;」 もしくは rc +」 である。半音下の音は rc 一」など
である。
あと言っておくべきことは 「 Y 」 によるレジスタへの直接書き込みである。チャンネル0
〜7であれば OPM , 8〜10であれば PSG のレジスタに書き込まれる。
また,1オクターブ上下の指定であるが,「〉」が上がる,「く」が下がるとなっている。
それから,音長(および一般的な数値の指定)には2とおりある。
1) r C 16」,「 T 120」,「 V 15」 のように,素直に害く方法。このとき数値は〇〜255の範
囲である
2) rc@512j のように「@」の後に続けて数値を害く。この場合の範囲は〇〜65535で
第11章 FM 音源277
ぁる。
3) の方法は連符の処理のために付けたものである。表 11-10 を見ていただきたい。これ
は各音長の長さの内訳である。たとえば 「 C 4」 は 「 C @256」 としてもまったく同じ長さの
音なのである。よって4分音符を3個に分けた3連符を鳴らしたい場合は256 = 85 + 85 +
86より, 「 C @85 C @85 C @86」 とすればよいのである。最後だけちょいと長めだが,まあ
人間の耳には分かるまい。
表 11-10 音調の内!/?
音符長 カウンタ 音符長 カウンタ
そして私がタコなためにしてしまったことであるが,「タイ」の指定に「&」と「& +」
の2とおりがある。
などという符は, 「 G 4& G 4」 となり,これは 「 G 2」 と同じであるべきだったのに,私はこ
こらへんの人情の機微を把握していなかったので,
& =直前の音符を Q 8 で鳴らすだけ
だと思ってしまったのである。これは非常にまずかった。で,「& +」を導入して逃げ
た。これにより,
= 「 C 4&+ C 4」= rc 2 j
278 試験に出る XI
= IC 4& D 4 J
とすればよいことになる。だが,やはり手抜きは手抜きなので,
「 C 4& + D 4」=「 C 4& + C 4」=「 C 2」
だったりする。少々面倒であるが,「&」と「& +」を使い分けることで我慢していただき
たい。
てなわけでリスト 11-6 のサンプルプログラムを見ていただきた V 、基本的な使い方を説
明すると,まずは演奏に先立って 「TEMPO 0」を実行すること。それから , 「MUSIC
A $ : : MUSIC B $ J=「MUSIC A $ + BS 」 である。このセミコロンはなかなかに強力
で,これにより1パートが255文字以内というマヌヶな制限が消える。なお演奏を止める
には 丨 CTRLl + C ^ I である。
では動作確認である。縁起もんだから馬鹿丁寧にやる。
1) NEW ON & HE 000 を実行。
2) LOADM " MML . BIN "
3) 「 VIP 」 のディスクカ、ら, LOADM、'CHOICED VOICE . VTD ",& HB 000 で,音色
のデータをロードする(もちろん VIP で作ったデータならほかのものでもかまわな
い )0
4) CALL & HA 8 B 0 を実行。
これで MML が使えるようになるのである0ちなみに B 000 H 〜 B 18 F H には「音色名」が
入っており, リスト 11-7 を 実行するとそれの 一覧表を 見ることができる。
リスト1トフ音色名の表示__
100 FOR 1=1 TO 20 : J=I^20
110 PRINT 拿
120 PRINT #0, J,MEM$(4HB0004.( J-l)tl0 f 10)
130 NEXT
ところで,ちゃんと動くことが分かったら,次には BASIC に組み込んでしまいたいとこ
ろであるが,面倒になったのでそこまではやってない。私がやったのは, 、、Start up.Bas"
の最後に実行される NEW を NEW ON &HB800 にして,自動的に機械語領域を確保す
るようにしたことと,
100 LOADM ' 、 MML. BIN"
110 LOADM 、'CHOICED VOICE. VTD" , &HB000
120 CALL &HA8B0
という小さなブログラムをディスクに用意しておくようにしたことだけである。こうして
おけば BASIC が立ち上がった後で,上記のブログラムを RUN するだけで MML が使え
るようになる。
念のために繰り返すが,音色データは LOADM '、(ファイル 名)", &HB000 で口ードアド
レスを指定するのを忘れないように。さもないと BASIC を壊して暴走するのである0
第11章 FM 音源279
おまけ T あ 3
表 1 1 H 1に VIP の音色デ ー タのフォーマットを示す。この章で作った MML では,30バ
イト目の KEY TRANSPOSE と35バイト目の SYC/LFO DELEY は使われていない。
また31,32, 33, 34バイト目のデータは, 最後の I コマンドで指定されたものが有効にな
る 0 よって必要があるならば,実行される I コマンドの順を変えたり, Y コマンドを使うこ
と。ただ,どうやら LFO に関しては無視してもかまわないようである(自信はないが)。
解説す3勿
最後に音 M の設定についてちょっとだけ説明しておく。 FM 音源で音 想; を変えるには,
「アルゴリズム ( ALG ) を見て,キャリアの TL だけを変える」のである。いままで説明し
なかったのだが,オペレータにはキャリアとモジュラの2とおりがあるのだ。アルゴリズ
ム〇〜3ではキャリアは OP 4 だけ,アルゴリズム4では OP 4 と OP 2 の二つ,アルゴリズ
ム5,6では OP 4, OP 3, OP 2 の三つ,アルゴリズム7ではすべてがキャリアとなってい
る。図 11-5 を見れば分かるだろうが,キャリアとはすなわち最終段にある(他のオペレー
夕を変調しない)オペレータのことである。
実際にリスト 11-4 の AF 61 h 〜 AFBB h でどんなことをやっているのかというと,
1) 音色データの TL の所をサーチして,最小の TL (つまり最大の音 M ) になっている
キャリアを見つける。
2) 1で見つけたキャリアの TL を V コマンドで指定された値にするための差を D と
する ( D =127 — V — TL : TL = 0なら V = 127 であることに 注意)。
3) すべてのキャリアの TL に D を加えて, OPM に書き込む。
という具合である。
注意 深く見るとあちこちに手抜きが発見できるがあまり 堅いことは言わないでいた
だきたい。
280 试験に出る XI
VIP の 音色 データ
音色名10文字 X 40
FM 音源 2 S 7
カラーイメージボードで取り込むのである
第 120 カラーイメージボ
取り込 C のIおる .
この章で取り上げるカラーイメージボードには CZ -8 BV 1 と CZ -8 BV 2 の二つがあるわ
けだ。 BV 1 と BV 2 の主な違いは, BV 2 では,スクランブル(ハーフトーン)回路のモー
ドが増えたことと,ハイスピードモノクロなどという技が付いたこと,それに320/640ド
ット,それぞれに対応するスクランブルモードが付いたことなどである。それはともか
く, 論より証拠で ある。さっさと 表12-1, 12-2 を見ていただきたい。
まず表 12-1 の CZ -8 BV 1 である。注意すべき点は,コマンド 10 H は1/1画面モード,リ
セットコマンド,スクランブル ON の三つの機能を兼ねているということである0よっ
て,1/4画面および1/16画面のときに,
スクランブル OFF —ON
に切り換えるなどするには,10„を出してスクランブルを ON にした後で,もう一度20„か
40„を出力して,画面モードを設定し直さなければならない0また,スクランブル OFF の
状態のままで,画面モードを1/4 — 1/1とするときなどは,1/1画面モードにすると同時に
スクランブルが ON になってしまうので,次に80„を出力して,スクランブルを OFF にし
なければならない。
表 12-1 CZ -8 BV 1
080 Oh
カラーイメー ジボードコントロール
OUT
080 1h
画像データ轿み込み
IN
> — — 1
•コマンド
10H n
1/1 画面モード + リセット+スクランブル ON
20H n
1/4 画面モード
40h" I
1/16 画面モード
80m 1 >
スクランブル回路 OFF
; 01h
次の1ラインを i 光み始める
02h
次のプレーン(色)を!光み始める ( B — R — G — B — …… )
04h 2)
コンピュータアクセスモード(バッファを!光み始める)
08h 2)
ビデオ信号入カモード(ビデオ信号をデジタイズし統ける)
注1: 1) および 2) のコマンドを出力した後は.最低 16.7 ms のウェイトを取ること(余裕
を持つて 17 ms 以上が望ましい)。ただし, 1) の後に 1) のコマンドが統くときならウェ
イトは必要ない。
注 2 :コマンド 01h を出力後. 2ms 以内に 1 ラインのデータを転送し終わること。また,こ
のコマンド 01 h を連 W して出力するときは, 6" s 以上の運延ウエイトを取ること。
注3:1/4, 1/16画面モードは横方向だけの縮小であるから,«方向はソフトウエアで「問
引く j 必要がある。
次に表12-2が0ヱ-88¥2である。 I / O アドレスが+ 2して,コマンドが四つ増えている
ことに注目。ここで注意しておかなければならないのが, CZ -8 BV 2 は,リセット時にスク
284 試験に出る XI
ランブルが「モード2」になっているということである。すなわち, CZ -8 BV 2 とはち よい
と違うスクランブルをするのである0具体的にどう違うかというと,はっきり言ってモー
ド2の方がより自然な中間色を表現しているのである。モード1では斜めの縞がどうして
も目立ったわけであるが,モード2ではそういうことは少なくなっているのである。ま
た,モード2のとき(だけ)はさらにスクランブルの仕方で,320/640ドットモードを選択
できるようになっている。これは「スクランブルの仕方」なのである0もともとは640ド
ットモードなのであるが,もしも本体の画面モードが320ドット (WIDTH 40) だった場
合は,320ドットモードのスクランブルの方がより自然に見えるようである0
表 12-2 CZ -8 BV 2
0802 m
カラーイメージポードコントロール
OUT
0803 h
画像データ1光み込み
| ■ ■ ■ ■ ■ ■■
IN
•コマンド
10m n
1/1 画面モード + リセット+スクランブル ON
20h u
1/4 画面モード
40 h u
1/16 画面モード
80 h "
スクランブル回路 OFF
01h
次の1ラインを!光み始める
02m
次のプレーン(色)を!充み始める ( B — R — G — B — …… )
04 h 2)
コンピュータアクセスモード(バッファを统み始める)
08 m 2)
ビデオ倌号入カモード(ビデオ信号をデジタイズし統ける)
81 h
スクランブルをモード1 ( BV 1 と同じ)にする
83 h
320 ドットモードのスクランブル
84 m
640 ドットモードのスクランブル
85 h
ハイスビードモノクロモード
;主1: CZ -8 BV 2 では,リセッ h 直後のスクランブルモードは「モード2の640ドットモー
ド j である。よって CZ -8 BV 1 と同じ動作をさせるためには.コマンド 81» i を荚行する必
要がある。
;主2 : 320/640ドットモードはモード2のときだけ*味を持つ(モード1では両者は同じ)。
実践す3负 T あ3
さっさとサンプルを出してしまうのである。 リスト 12-1, 12-2, 12-3, 12-4 であ
る 0 リスト 12-1 は XI 用,リスト 12- 2は機械語部分,リスト 12- 3は turbo 用,リスト
12-4 は機械語部分である。リスト12-1, 12-3 ともに,一般的な変更箇所は,
• 130行の I / O アドレス
• 170〜190行のモード設定
となっている。 CZ -8 BV 1 を使っているならば,130行を,
130 CP = & H 800 : DP 二 & H 801
としていただきたい。170〜190行は画面の大きさの選択である。「’」 ( REM ) で殺してな
い行が選択されるわけだ。おっと,今気が付いたがこの場合はどちらも WIDTH 80のモー
ドで走らせていただきたい。
第12章 カラーイメージボード 285
スト 12-1 XI 用画像 取り込みプログラム(遅い)_
100 * FOR XI
110 INIT : CLS4:DEFINT B-Z
120 CLEAR &HE000
130 CP=&H 80 2 : DP=&H 803
140 MEM$ (&HE000 f 16) =HEXCHR$ ( ff EB 4E 23 4616 50 D9 01 03 08 ED 78 D9 ED 79 03 ff )
150 MEM$(&HE010 f 15)=HEXCHR$( tf 15 D9 20 F6 C9 ff )
160 DEFUSR0=&HE000
170 XS=80 : YS=200 : MD=&H10 : SL=1 : f 640t200
180 f XS = 40:YS = 96 : MD = &H20:SL = 2 : f 320 拿 96
190 f XS = 20:YS = 48 : MD = &H40 : SL=4 : 1 160t48
200 MEM$(&HE008 f 2)=MKI$(DP)
210 POKE &HE005 f XS
220 OUT CP,&H10 : 1 RESET
230 OUT CP,MD : 1 1/1 f 1/4 f 1/16 MODE
240 1
250 OUT CP f &H 4 : •COMP ACCESS (LATCH)
260 PAUSE 1
270 ADR = &H4 000 : GOSUB tf IS M
280 ADR = &H8000 : GOSUB ,f IS fl
290 ADR = &HC000 : GOSUB ,f IS ft
300 OUT CP.&H8 : 1 VIDEO ACCESS
310 PAUSE 1
320 GOTO 250
330 END
340 f
350 LABEL #f IS M
360 OUT CP f &H 2 : • RGB
370 FOR 1=1 TO 24
380 OUT CP,1 : f SET NEXT 1 LINE
390 NEXT
400 FOR Y=1 TO YS
410 D=INP(DP) : D=INP(DP) : D=INP(DP): f SKIP 3
420 D$=USR0(MKI$(ADR))
430 ADR = ADR-f&H800
440 IF (ADR AND &H3800)=0 THEN ADR=ADR-(&H4000-80)
450 FOR 1=1 TO SL
460 OUT CP,1 •ノ PAUSE 0 : f SET NEXT 1 LINE
470 NEXT
480 NEXT
490 RETURN
リスト 12-2 カラーイメージボード— G - RAM へ 1 ライン転送
.Z80
•
.PHASE
0E000H
;OR ANY PLACE
E000
EB
•
EX
LD
DE,HL
E001
4E
C,(HL)
E002
23
INC
HL
E003
46
LD
B,(HL)
: BC=VRAM ADDR.
E004
16 50
LD
D f 80
;XS
E006
D9
EXX
E007
01 0803
LD
IN
BC,0803H
;DPORT
E00A
ED 78
LOOP :
A, (C)
;GET 1 BYTE
E00C
D9
EXX
E00D
ED 79
OUT
(C),A
;TO VRAM
E00F
03
INC
BC
D
;INC VRAM ADDR.
E010
15
DEC
: DEC COUNTER
E011
D9
EXX
E012
20 F6
•
JR
NZ f LOOP
E014
C9
t
•
RET
9
END
リスト 12-3
turbo 用画像取り込みブログラム(遅い)
100 f FOR
turbo
110 INIT : CLS4:DEFINT B-Z
120 CLEAR &HE000
286 试験に出る XI
130 CP=&H802 : DP=&H803
140 MEM$(&HE 000,12 い HEXCHR$("78 EB 0180 IF 04 ED A3 3D 20 FA C9"}
150 1
160 DEFUSR0=&HE000
170 XS=80 : YS=200 : MD=&H10 : SL=1 : *640*200
180 f XS = 40:YS = 96 : MD = &H20 : SL=2 : * 320*96
190 f XS=20 : YS=48 : MD=&H40:SL=4 : , 160*48
200 OUT CP.&H10 : 1 RESET
210 OUT CP,MD : 1 1/1,1/4 f 1/16 MODE
220 DMA$=DMA$+CHR$(&B111 1001 >+MKI$(&H4000)+MKI$(XS-l>
230 DMA$=DMA$+CHR$(&B11100 f &B101 000 f &B11001101)
240 DMAS = DMA$-fMKI$ (DP)+CHR$(&B1001 1010)
250 D$=USR0(DMA$)
260 PAUSE 1
270 1
280 DMA$=CHR$ ( &B1 100 1) 4-MKI $ ( 0 ) -f HEXCHRS ( M CF 87">
290 OUT CP f &H4 : , COMP ACCESS (LATCH)
300 PAUSE 1
310 ADR=&H4000:GOSUB"IS"
320 ADR=&H 800 0 : GOSUB"IS M
330 ADR=&HC000 : GOSUB H IS M
340 OUT CP f &H8 : , VIDEO ACCESS
350 PAUSE 1
360 GOTO 290
370 END
380 •
390 LABEL M IS M
400 OUT CP,&H2 : f RGB
410 FOR 1=1 TO 24
420 OUT CP f 1 : , SET NEXT 1 LINE
430 NEXT
440 FOR Y=1 TO YS
450 D=INP(DP) : D=INP(DP) : D=INP(DP): f SKIP 3
460 MID$(DMA$ f 2,2)=MKI$(ADR)
470 D$=USR0(DMA$)
480 ADR = ADR-f&H800
490 IF (ADR AND &H3800 い 0 THEN ADR=ADR-(&H4000-80)
500 FOR 1=1 TO SL
510 OUT CP,1:'PAUSE 0 : , SET NEXT 1 LINE
520 NEXT
530 NEXT
540 RETURN
リスト 12-4 文字列— DMA 転送
.Z80
•PHASE 0E000H ;OR ANY PLACE
E000
78
LD
E001
EB
EX
E002
01 1F80
LD
E005
04
LOOP :
INC
E006
ED A3
OUT I
E008
3D
DEC
E009
20 FA
JR
E00B
C9
•
RET
t
END
; DE=ADDRESS TO DATA,B=COUNTER
A,B
DE V HL
BC,1F80H
B
NZ.LOOP
;HL POINTS DATA
;DMA I/O ADDR.
プログラムの説明に入る。まずはリスト 12-1 である。大事なのは140,150行で機械語
ルーチンを用意している点である。この機械語ルーチンは手抜きしてあるので,200, 210
行で一部を書き換えたりしていてあまりよくない。
さて,まずは220行である0これはコントロールポートに10„を出力しているわけだ。こ
れが何かと見るならば,表 12- 1より明らかなように,「1/1画面モード十リセット+スク
第12章カラーイメージボード 287
ランブル ON 」 なわけだ。その次の230行では再びコントロールポートに MD を出力して
いる。これは何かと見るならば,結局 MD は 10 H , 20 h , 40 h のうちのどれかなのである。
MD =10„ の場合は,先程と同じ命令を繰り返すことになるわけだから,ま,無駄というこ
とになる。そこで MD = 20„ の場合を説明するのである。
コント ロール ポートに 20 H が出力される前は,カラーイメージボードは1/1画面モード
でシヤコシヤコとビデオ入力をデジタイズしていたわけである。すなわち,カラーイメ
-ジボードはビデオ画面を640ドット X 200 ドット=80バイト X 200 ライン(実を言うと
本当はもっと大きいのだが)のデータに変換していたのである。そこへ20„というコマンド
が来たわけである。そうすると,カラーイメージボードはそれまでの 640 X 200 をやめ
て,ビデオ信号を320ドット X 200 ドット=40バイト X 200 ラインのデータに変換するよ
うになるのだ。縦の方は200ラインのまま変わらないということに注意。もしもこれが 20 h
でなく 40 H であったなら,160ドット X 200 ドット=20バイト X 200 ラインとなる(ここで
は簡単に説明するために「200ライン」と書いてあるが,実はカラーイメージボードはもっ
と多くのラインを取り込んでいるのである。実際に表示するのはそのうちの200ラインと
いうことになる)〇
これらのデータを変に潰れたり,伸びたりせずに表示させるには,コンピュータの画面
モード ( WIDTH ) との関係で表 12- 3のようにすることになる。
表 12-3 カラーイメージボードと本体の画面モード
WIDTH 40
- 1
WIDTH 80
丨
80バイト X 200 ラインをそのまま G-RAM
へ(画面全体に表示)
m
40バイト x 200ラインを1ラインおきに
G - RAM へ(画面の1/4に表示)
1/16 = 30 h
-1
20バイト x 200ラインを1ラインおきに
G - RAM へ(画面の1/4に表不)
- - - — -- 】
20バイト x 200ラインを3ラインおきに
G - RAM へ(画面の1/16に表示)
さてここからが佳境である。リスト 12- 1の250行でコントロールポートに04„を出力し
ている0これは表 12-1 にもあるように,「コンピュータアクセスモード」なのである。早
い話が,カラーイメージボードはこのコマンドを受け取ると,それまで シャカシャ カとデ
ジタイズしていたのを やめて, 「よっしゃよっしゃ,デジタイズしたデータが欲しいんだ
な。ようし,イキのいいやつをデジタイズして渡してやらあ。受け取りな,ほうら」とな
るわけである。すなわち,カラーイメージボードは,自分の持っている バッファを一 杯に
した後で「データ転送モード」に入るのである(表 12-1 の注1にもあるように, バッファ
が一杯になるまで,最悪の場合17 ms 待たなければならない)。
その次の270〜290行では青,赤,緑の順でカラーイメージボードから G - RAM に転送し
ている。
というわけで,350行からのサブルーチン " IS " の説明である。
まずは360行で「2」を OUT している。これは言わずと知れた B —R —G — B ……な
288 試験に出る XI
わけだ。次に370〜390行のループであるが,これは24行の空読みである。先程書いたよ
うに,カラーイメージボードは実際は200ラインよりも多くのライン数を取り込んでいる
のだ。それで,ちょうどおいしい所だけを表示するために,最初の方は空読みして捨てて
いるのである。それから410行である。今度は3バイトの空読みである。何でこうするの
かというと,それはカラーイメージボードのハードがそうなっているからである。試しに
410行を削除してみると,表示が少し右にずれるのが分かるだろう。後は420行で1ライン
転送し,430行,440行で G - RAM アドレスを1ライン下げ,450〜470行で(カラーイメ
ージボード側の)ラインのスキップをやっている。
以上で 一 とおり説明は終わりである。170〜190行で注釈にしてある行を復活して大きさ
の違う画面を表示したり, YS の値を大きくしたり, SL の値をいじったりして楽しんでい
ただきたい。
リスト 12- 3の turbo 版は,データの転送に DMA を使っていること以外は変わったこ
とはないので,説明は省略する。
気分は近未来 T あ3
さて,ここからぼちぼち フィニッシュに 持ち込むのである。そして一体何をやるかとい
うと , 「BASIC + 動画面のウィンドウ」なのである。
種を明かすと, CTC の割り込みを使って, BASIC と画像取り込みが並列動作してしまう
のである。言葉で言うと簡単に聞こえてしまうが,これはちょっと他機種ではまねができ
ないワザであろう。 BASIC がちゃんと動いている同じ画面で,1/16 ( もしくは 1/4) の画
面がリアルタイムで動いているのである。これを見てむむむとうならない奴はいないであ
ろぅ。
で,このよ一に BASIC + 画像取り込みが(一応)マルチタスクすると,どういうメリッ
卜があるかというと,
1) 他機種のューザーに自慢できる
2) 他機種の ューザーが 驚く
3) 他機種のューザーが落ち込む
4) 他機種の ューザー が穫返る
5) テレビを見ながらプログラムや,機械語のダンブリストを入力できる(スーパーイ
ンポーズよりずっと目触りがよい)
6) 近未来の気分を味わえる
となっている。とにもかくにも,8色ながらも「動画面のウィンドウ」なのである。こん
な SF っぼいことを,8ビットの turbo (と CTC を持つ XI )でできてしまうのだだだっ!
と逆上しつつ,ブログラムの説明になだれ込むのであった。
リスト 12- 5が XI 用のアセンブルリスト, リスト 12- 6がそのダンブリスト ( CRC チェ
ックサム付き:付録 A を参照), リスト 12-7 が turbo 用のアセンブルリスト, リスト 12-
8がその CRC チェックサム付きダンプリストとなっている。
第 12 聿 カラーイメージボード 289
X SIZE
Y SIZE
UP PASS LINES
LEFT PASS BYTES
1 ;SKIP LINES
10H.00H
00H f 00H f 00H f 00H f 00H
XS : DB
YS : DB
UPPASS : DB
LTPASS : DB
•
STIME : DB
MODES : DB
DB
KFAC
.Z80
.PHASE 0EF00H
COMMANDS 10H
20H
40H
80H
01H
02H
04H
08H
CZ-8BV2
81H
83H
84H
85H
RESET,1/1
1/4
1/16
HALF TONE OFF
NEXT 1 LINE
NEXT PLANE(B->R->G->B..y
COMP ACCESS
VIDEO ACCESS
HALF TONE=MODEl
X=320 MODE
X=640 MODE
MONO COLOR MODE
EF10
EF13
EF14
EF15
EF16
EF17
EF18
EF19
EF1A
EF1B
EF2F El
EF30 E5
EF31 CB B4
EF33 CB FC
EF35 CD EF52
EF28 2A EF0E
EF2B E5
EF2C CD EF52
EF1C ED 4B EF0C
EF20 3E 04
EF22 ED 79
EF24 D9
EF25 CD EFBE
EF0C 0802
KF0E 4000
EF05 10 00
EF07 00 00 00 00
EF0B 00
EF04 01
EF0O 50
EF01 C8
EF02 01
EF03 01
そして使い方は リスト 12-9 〜 12-12 である。
順に説明しよう。
おのおののダンプリストを打ち込み,リスト 12-6 は,
SAVEM '' BV . CPU ", & HEF 00,& HEFC 6
でセーブする0
リスト 12- 8ならば,
SAVEM 、、 BV . DMA ", & HEF 00 ,&HEFEE
である0チェックサム(および CRC ) の確認を確実にすること。
リスト 12-5 XI 用画像取り込みプログラム
0
0 0
8 2 11
D 355559555
CFFCDEDCDG
試験に出る XI
EF47
EF48
EF49
EF4A
EF4B
EF4C
EF4D
EF4E
EF38 El
EF39 CB FC
EF3B CD EF52
EF3E 3E 08
EF40 D9
EF41 ED 79
EF4 3 D9
EF44 CD EFBE
EF4F FB
EF50
C9
EF51
00
EF52
3E
02
EF54
D9
EF55
ED
79
EF57
D9
EF58
CD
EF91
EF5B
3A
EF01
EF5E
5F
EF5F
CD
EF9F
EF62
44
EF63
4D
EF64
3A
EF00
EF67
57
EF68
D9
EF69
03
EF6A
ED
78
EF6C
D9
EF6D
ED
79
EF6F
03
EF70
15
EF71
D9
EF72
C2
EF6A
EF75
0B
EF76
D9
EF77
3A
EF04
EF7A
CD
EF94
EF7D
3E
08
EF7F
84
EF80
67
EF81
E6
38
EF83
C2
EF8C
EF86
01
3FB0
EF89
B7
EF8A
ED
42
EF8C
ID
EF8D
C2
EF5F
EF90
C9
EF91
3A
EF02
EF94
D9
EF95
16
01
EF97
ED
51
EF99
3D
EF9A
C2
EF97
EF9D
D9
EF9E
C9
EF9F
D9
EFA0
0C
EFA1 3A EF03
POP
SET
HL
7,H
CALL
IMAGES
LD
A.08H
EXX
OUT
(C) ,A
EXX
CALL
DELAY
POP
HL
POP
DE
POP
BC
EXX
POP
HL
POP
DE
POP
BC
POP
AF
EI
RET
NOP
;VIDEO ACCESS
: BC f =(CPORTA)
;LOAD REGISTERS
;OR RETI
IMAGES :
LD
A 9 02H
;NEXT PLANE
EXX
; BC f =(CPORTA)
OUT
(C) ,A
•
EXX
•
CALL
DUMYV
SKIP LINES
LD
LD
A f (YS)
LINE COUNT
E f A
E=COUNTER
I MAY :
CALL
DUMYH
SKIP BYTES
LD
B f H
LD
C f L
;COPY ADDRESS
LD
A f (XS)
LD
D f A
;COUNTER
EXX
卜
1
BC^iCPORTA)
INC
BC ;
: BC f = (DPORTA)
POO :
IN
A,(C) ;
READ 1 BYTE
EXX
OUT
(C) f A ;
TO VRAM
INC
BC ;
D ;
INC VRAM ADDR.
DEC
DEC COUNTER
EXX
JP
NZ.POO
DEC
BC :
BC*=(CPORTA)
•
EXX
t
LD
A f (STIME)
•
CALL
NEXTL ;
SKIP LINES
•
LD
A,8 ;
DOWN 1 LINE
ADD
A t H
LD
H f A
AND
38H
JP
NZ f IMANEX
LD
BC f 4000H-
80
OR
A
SBC
HL.BC
IMANEX:
DEC
E
JP
NZ f IMAY ;
LOOP
RET
;?? LINES PASS
DUMYV : LD
•
A f (UPPASS)
NEXTL : EXX
: BC 1 =(CPORTA)
LD
D t 01H ;1L DOWN
NEXTL1 : OUT
(C) f D
DEC
A
JP
NZ f NEXTL1
EXX
RET
•
t
;?? BYTES SKIP
DUMYH : EXX
: BC f =(CPORTA)
INC
C ; BC , =(DPORTA)
LD
A,(LTPASS)
11
E D
19 1111
c D E D c F
第 12 章カラーイメージボード
X SIZE
Y SIZE
UP PASS LINES
LEFT PASS BYTES
50
FB
4B EF0C
EF05
79
EFBE
F5
0A37
FB
CZ-8BV2
81H HALF T0NE=M0DE1
83H X=320 MODE
84H X=640 MODE
85H MONO COLOR MODE
01H NEXT 1 LINE
02H NEXT PLANE(B->R->G->B" >
04H COMP ACCESS
08H VIDEO ACCESS
COMMANDS 10H RESET t 1/1
20H 1/4
40H 1/16
80H HALF TONE OFF
)MA
EQU
1F80H
,Z80
•PHASE OEF00H
EF00
EF08
EF10
EF18
EF20
EF28
EF30
EF38
EF40
EF48
EF50
EF58
EF60
EF68
EF70
EFA4
EFA6
EFA7
EFA9
EFAA
EFAB
EFAC
EFB0
EFB3
KFB4
EFB5
EFB6
EFB7
EFB9
EFBC
EFBE
EFC1
EFC2
EFC3
EFC4
EFC6
F5 DA 90 88 42 94IF 75 92ED
リスト 12-7 XIturbo 用画像取り込みプログラ
DUMYHL :
IN
DEC
JR
DEC
EXX
RET
D f (C)
A
NZ,DUMYHL
C
;BC
=(CPORTA)
INIT :
INITO :
LD
LD
LD
INC
OR
RET
OUT
CALL
JR
BC,(CPORTA)
HL,MODES
A f (HL)
HL
A
Z ;END MODE SET
(C) f A ;SET BV MODE
DELAY
INIT0
DELAY : LD
DELAYL : DEC
LD
OR
JR
RET
DE t 2615 ;10
DE ;6
A • D ;4
E ;4
NZ,DELAYL
;10
; 12/7
10+10M6 + 4 + 4 +12 > 拿 2615-12 + 7 = 68005
=17.00125ms
END
4 8
62
E2
ス
ス
ダ
SUM
98168C
0
0 0
8 2 11
B BBB
D D D D
s s
s s
• • • .pp
s s p T
c f J 一
D D 0 D 9 9
E 3 2 0 D c
D1E378DD8 1BA309
E272BCEC1 11 7 B 2 c
BAFBBB9C3A13F37
24C8FF3F7C2A982
005FF1F81B9D73A
04EEEEE0EFDC503
005CEF2EF19FF99
00D0BE53EF75E7D
085BD2DFE1DF0DB
10C4C5CEBCEE0E0
125D9DC2D191A9F
0OFEDCF5CDD03DE
103595 BD912AD8A
00FE7ECCDE 03476
10F5DF4C99EF4D2
00EDEEBF7D3E4EC
80C54EBBD101F39
C0AC00CCEC09E0D
00D9EA 51919 DF95
50CD32EEDDCC9D1
32112 D286
75D5DD243
0FD90FD7
BEED2EE3
1F19DC 819
050C30C1C
F2690B75B
EC1D54BFF
CD9FDD380
81DEEE212
22F7F9EF3
C4E9EC7EB
8D2239FEA
3E0C0DEB7
67ADAD5DB
EB 33300 cl
7F91CB19A
63C50F270
292 試験に出る XI
EF4F
EF50
EF51
EF04
01
EF05
10
00
EF07
00
00 00 00
EF0B
00
EF0C
0802
KF0E
4000
EF10
CD
KFAA
EF13
F3
EF14
F5
KF15
C5
EF16
D5
EF17
E5
EF18
D9
EF19
C5
EF1A
D5
EF1B
E5
EF1C
ED
4B EF0C
EF20
3E
04
HF22
ED
79
EF24
D9
KF25
CD
F.FE6
EF28
2A
EF0E
EF2B
E5
EF2C
CD
EF52
EF2F
EF30
El
E5
EF31
CB
B4
EF33
CB
FC
EF35
CD
EF52
EF38
El
EF39
CB
FC
EF3B
CD
EF52
EF3K
3E
08
EF40
D9
EF4 1
ED
79
EF43
D9
EF44
CD
EFE6
STIME :
DB
1 ;
SKIP LINES
MODES :
DB
10H f 00H
DB
00H f 00H f 00H t 00H f 00H
CPORTA :
DW
0802H ;
OR 800H
TOPA :
•
DW
4000H
START :
CALL
INIT ;INIT BV f DMA
ENT :
DI
PUSH
PUSH
AF
BC
PUSH
PUSH
EXX
DE
HL
PUSH
BC
PUSH
DE
PUSH
HL ;
SAVE REGISTERS
t
LD
LD
BC f (CPORTA)
A.04H
COMP ACCESS
OUT
(C) ,A
LATCH
EXX
BC 1 =(CPORTA)
•
CALL
DELAY
•
LD
HL•<TOPA) ;VRAM ADDRESS
PUSH
H し
•
CALL
IMAGES ;BLUE
•
POP
HL
PUSH
HL
RES
6 f H
SET
7tH
眷
CALL
IMAGES ;
;RED
%
POP
SET
HL
7.H
•
CALL
IMAGES
;GREEN
t
LD
A V 08H
;VIDEO ACCESS
EXX
: CPORTA)
OUT
(C) f A
•
EXX
•
•
CALL
DELAY
§
POP
POP
HL
DE
POP
BC
EXX
POP
HL
POP
DE
POP
BC
•
POP
AF
;LOAD REGISTERS
t
El
RET
;OR RETI
NOF
#——————
IMAGES :
LD
A.02H
;NEXT PLANK
EXX
;BC»=(CPORTA)
OUT
(C) f A
#
EXX
•
CALL
DUMYV
SKIP LINES
LD
LD
A f (YS)
LINE COUNT
E f A ;
E=COUNTER
IMAY:
CALL
DUMYH
SKIP BYTES
し D
LD
BC t DMA
DMA ADDRESS
A f 0001100 IB ; WR0
OUT
<C) f A
OUT
(C) f L
OUT
(C) f H
;SET VRAM ADDRESS
LD
A f 0CFH
; WR6 LOAD
OUT
(C) f A
LD
A f 87H
; WR6 ENABLE
OUT
(C) f A
2 4 5 7 8BEF2579BDF13
5 5 5 5 5555666666677
FFFF FFFFFFFFFFFFF
E E E E EEEEEEEEEEEEE
2 9
0 7
FI D 0
8 0 9 8
F F FF9991F979
E E E11766C787
11191111
EDCDEDCF
B 9 0
F c 0
E 9 D 9 DAFD1EDDDEDED
3DED C35C03EEE3E3E
7 8
4 4
F
E
9 A B c D E
4 4 4 4 4 4
F F F F F F F
E E E K E E E
第 12 章カラーイメージボード
4B EF0C
EF05
07
79
EFE6
F4
EF00
00
EFDE
EF0C
EFE3
EFA2
EFA4
EFA5
EFA7
EFA8
EFA9
EFAA
EFAE
EFB1
EFB2
BFB3
EFB4
EFB6
EFB8
EFBB
EFBD
EFC0
EFC1
EFC3
EFC4
BFC7
BFCA
EFCB
EFCE
EFD1
BFD3
EFD6
EFD7
EFD9
EFDA
EFDC
21 EFDD
3E 09
011F80
04
ED A3
3D
20 FA
C9
EFDD
EFDE
EFE0
KFE1
EFE2
EFE3
EFE5
EFE6
61
1C
28
CD
9A
EFE6
EFE9
EFEA
EFEB
EFEC
EFEE
11 0A37
IB
7A
B3
20 FB
C9
EF9D D9
EF9E 0C
EF9F 3A EF03
EF75 3A EF04
EF78 CD EF92
EF7B 3E 08
EF7D 84
EF7E 67
EF7F E6 38
EF81 C2 EF8A
EF84 013FB0
EF87 B7
EF88 ED 42
EF8A ID
EF8B C2 EF5F
EF8E C9
EF8F 3A EF02
LD
A t (STIME)
•
CALL
NEXTL ;SKIP
LINES
•
LD
A,8 ;DOWN
1 LINE
ADD
a 9 h
LD
H f A
AND
38H
JP
NZ,IMANEX
LD
BC f 4000H-80
OR
A
SBC
HL f BC
IMANEX :
DEC
E
JP
NZ f IMAY ;LOOP
•
RET
•
;?? LINES PASS
DUMYV :
•
LD
A,(UPPASS)
NEXTL :
EXX
;BC 1 =
(CPORTA)
LD
D f 01H ; 1L DOWN
NEXT い:
OUT
(C) t D
DEC
A
JP
NZ.NEXTL1
EXX
RET
;?? BYTES SKIP
DUMYH :
EXX
; BC f =(CPORTA)
INC
C ;BC f = (DPORTA)
•
LD
A,(LTPASS)
DUMYHL :
IN
D, (C)
DEC
A
JR
NZ,DUMYHL
DEC
C
EXX
; BC»=(CPORTA)
•
RET
INIT :
LD
BC,(CPORTA)
LD
HL f MODES
INIT0 :
LD
A,(HL)
INC
HL
OR
JR
A
Z f INIT1 : END MODE SET
OUT
(C) f A : SET BV MODE
CALL
DELAY
•
JR
INIT0
INIT1 :
LD
A,(XS)
LD
L,A
LD
H f 0
DEC
HL
LD
LD
(DMAXS) f HL ;SET X SIZE
HL,(CPORTA)
INC
HL ; HL=DPORTA
•
LD
(DMAPDA) f HL
t
LD
HL.DMADT
LD
A f DMADTE-DMADT
SETDMA :
LD
BC f DMA
SDMAL : INC B
OUTI ;OUT TO DMA
DEC A
JR
NZ,SDMAL
•
RET
DMADT :
DEFB
0110000 IB
WR0
DMAXS :
DEFS
2
LENGTH
DEFB
00011100 B
WR1
DEFB
00101000 B
WR2
DEFB
1100110 LB
WR4
DMAPDA :
DEFS
2
PORT B ADR.
DEFB
10011010 B
WR5
DMADTE :
DELAY :
LD
DE.2615 ;10
DELAYL :
DEC
DE ;6
LD
A f D ;4
OR
E ;4
JR
NZ,DELAYL ;
;12/7
RET
;10
D1E378DD8 AF6B2A32
E272B2EC1 36222222
0 B
5 F
D D 0 D 9 9
E 3 2 0 D c
5
9
11 F
0 5 E
9 6 D D 2 9 9
D 1 E 3 c D c
2 3 5 7 8 B c
9 9 9 9 9 9 9
F F F F F F F
E E E E E E E
拭験に出る XI
EF00
EF08
EF10
EF18
EF20
EF28
EF30
EF38
EF40
EF48
EF50
EF58
EF60
KF68
EF70
EF78
EF80
EF88
EF90
EF98
EFA0
EFA8
EFB0
EFB8
EFC0
EFC8
EFD0
EFD8
EFE0
EFE8
1A
5F
5C
07
94
FB
DC
D7
D9
10
C7
2F
CC
36
SUM : C0 C8 B0 5D 52 C0 51 0C 3533
SUM : B4 77 EE 11 CA 97 49 2B F2C9
次に小手しらべである 0 まず XI ユーザーは リスト 12-9 を , turbo ユーザーは リスト12
-10 を打ち込む (120 行が1行違うだけである)。暴走すると元も子もなくなるのでセーブ
を忘れないように。
それから RUN すると(あらかじめ機械語部分を LOADM でロードしておいた方がよ
い),全画面取り込みが始まるのである。それがうまくいったらこっちのものである。
| SHIFT 1+ 丨 BREAK | で止めていただきたい。次に130〜160行をリスト 12-11, 12-12 の
ように打ち換えてそれぞれセーブしていただきたい。おのおのが1/4画面,1/16画面の取
り込みを実行するのである。
ここらで CZ -8 BV 2 を持っている人のための腕慣らしである。リスト 12-11 の150行に
ある コマン ドの並びを,
HEXCHR $('、10 20 83
としていただきたい。よく観察した後で, BREAK して,次には,
HEXCHR $(、'10 20 84
としていただきたい0どうだ,微妙にスクランブルのパターンが違うであろう0これが320
ドットと640ドットモードの違いである。
次に同じようなことを,
HEXCHR $('、10 20 81
と,
HEXCHR$riO 20 00……
でもやっていただきたい0これがモード1とモード2の違いである0確かにモード2の方
が自然な感じであろう。また,モード1では,320/640ドットの違いがないということもチ
エックしていただきたい。さらには申し訳ないのだが,ハイスピードモノクロに関しては
自習ということにする。機械語ブログラムを適当に書き換えるなどしてみて欲しい。モノ
第 12 聿 カラーイメージボード 295
^ BV . DMA 々でセーブ
ス
-7」のタンブ
68005
17.00125ms
BADB3B9CBA11 0715
24C82F3F9C2A71D6
005FF1F81B9DDDF6
04EEEEE0EFDCEEEE
005C6F2EF19F9F47
00D0EE53EF751C06
085BD2DF61DFEEA4
10C4C5CEECEE 3338
125D9DC2D191F198
00FEDCF5CDD 01670
103595 BD912A0DDE
00FE7ECCDE038EK3
10F5DF4C99EF197F
00EDEEBF7D3E068E
80A54EBBD10FFDE2
C0AC00CCEC08EE39
00D9EA 51919 DD99D
50CD32EEDDCC977C
ADAD59FADDE7
333007 E2DE13
F91CB1D0F14D19
3C50F2E0E20E1C
0FD90F7AEFF1AB
BEED2E03DE169F
1F19DC 842309 D0
050C302F2E8CC2
F2690B78B21AC3
EC1D54B1220F0B
AD9FDD3F0390DA
81 DEEE2E 0202 C7
22F5F9E66FED8B
C4E9EC7E2E 3321
8D 2239 FDFCF3CA
3EOC0DEC60EA10
クロであるから,パレットを替えて,1画面だけ転送すればよいのである。
リスト 12-9 XI 用全画面取り込み
100 INIT : , 1/1 MODE
110 CLEAR &HEP00
120 IF MEM$(«cHEF10,3> く〉 HEXCHR$<"CD AC EF" > THEN LOADM "BV.CPU"
130 MEM$(&HEF00,4)=CHR$(80,200,24,3)
140 MEM$(&HEF04 f 1)=CHR$(1)
150 MEM$(iHEF05 f 7)=HEXCHR$( M 10 00 00 00 00 00 00**)
160 MEM$(&HEF0C,4)=MKI$(&H802)+MKI$ < &H4000)
170 CALL &HEF10
180 CALL &HEF13 : GOTO180
リスト 12-10 XIturbo 用全画面取り込み
100 INIT : , 1/1 MODE
110 CLEAR &HEF00
120 IF MEM$(&HEF10 t 3)OHEXCHR$( M CD AA EF") THEN LOADM "BV.DMA"
130 MEM$(&HEF00,4)=CHR$(80 f 200 ,24,3)
140 MEM$(&HEF04 f 1)=CHR$(1)
150 MEM$(&HEF05 f 7)=HEXCHR$( M 10 00 00 00 00 00 00 M )
160 MEM$ ( &HEF0C , 4 ) =MKI $ ( &H802 ) -fMKI $ ( &H4000 )
170 CALL &HEF10
180 CALL &HEF13 : GOTO 180
リスト 12-114 分の 1 画面取り込み用変更点
130 MEM$(&HEF00 f 4)=CHR$(43, 116, 1,2)
140 MEM$(&HEF04 f 1)=CHR$(2)
150 MEM$(&HEF05 f 7)=HEXCHR$( M 10 20 00 00 00 00 00"}
160 MEM$(&HEF0C f 4 )=MKI$(&H802)*fMKI$(4H4000-f37-f80>10)
リスト 12-1216 分の 1 画面取り込み用変更点
130 MEM$(&HEF00 ,4 )=CHR$( 21 ,58,1,2)
140 MEM$(&HEF04 ,1 )=CHR$( 4 )
150 MEM$(&HEF05 f 7)=HEXCHR$( M 10 40 00 00 00 00 00")
160 MEM$(&HEF0C f 4 )=MKI$( &H802)-f MKI $(&H4 500 + 594-80)
さて,ここからがキメである 0 1/16画面の取り込み ブロ グラム (1/1 画面でも1/4画面
でもいいが)の180行以降を リスト 12-13 ( turbo 用)もしくは リスト 12-14 ( XI 用)のよ
うに書き換えるのである。そうすれば BASIC は 「 OK 」 とメッセージを出すが,画像取り
込みは相変わらず行なわれている0すなわち マルチタスク (?) のでき上がりである。 た
だし, XI 用の方は, FM 音源ボード ( CZ -8 BS 1) か,立体視ボード ( CZ -8 RB 1)
か, RS -232 C •マウスボード ( CZ -8 BM 2) が必要である。 そして,それぞれの 場合に お
いて200〜220行にあるように 「CTC 二〜」のアドレスを書き換えること。リスト 12-14 で
は FM 音源ボー ドに 対応す るようになっている。
このプログラムはなかなかに趣があるわけだが,欠点は少々キーの反応が悪くなること
である。 turbo の場合は TEMPO 文で適当に調節していただきたい (「TEMPO 30」で画
296 試験に出るXI
像取り込みが一番遅くなる)。 XI の方では,300行と320行で CTC に送っている値 (30 と
125) を大きくすると画像取り込みが遅くなり,小さくすると速くなる。これについては第
5章を参照のこと。ところでリスト 12-14 では190行で 「POKE & H 61 AE , 1」とやって
いるが,これは BASIC を書き換えて, 「 LIST 」 命令を実行してもグラフィックが OFF に
ならないようにしているのである(ただし 「 FILES 」 などでは OFF になる)〇ちなみに turbo
では(リスト 12-13 ではやってないが ), 「POKE & H 14 F 9, 1」とすることによって,
「 LIST 」 を実行してもグラフィックが OFF にならなくなる。
なお注意しておくが,リスト 12-13 の200行は「割り込みを禁止せずにベクトルテープ
ルを書き換えている」ので,とんでもない反則である。やりすぎると暴走する。また,リ
スト12-13, 12-14 は「何度も RUN させてはいけない」のである。つまり,割り込みを禁
止せずに割り込み処理ルーチンのワークをいじることになるからである。すなわち,2度
目の RUN 以降はロシアンルーレツトみたいなものである。
また,ブログラム中で DELAY というサブルーチンを使っているが,その時間はドブに
捨ててしまっているのである。つまり, CTC をうまく使うともっと時間を有効に使え,
BASIC のキー反応が向上するのである。それらに関しては自由研究としておきたい。
リスト 12-13 XI turbo 用テレビインリスト変更点 (turbo BASIC 用)
180 TEMPO 80
190 MEM$(&HEF50 f 2)=HEXCHR$( M ED 4D M )
200 MEM$(&HF81E f 2)=MKI$(&HEF13)
リスト 12-14 XI 用テレビインリスト変更点 (NEW BASIC では動かない)
180
MEM$(&HEF50,2)=HEXCHRS("ED 4D" >
190
POKE &H61AE,
1 : , IF TAPE BASIC THEN
&H68E2
200
CTC=&H704
: f CZ-8BSl
210
f CTC=&HA04
: f CZ-8BRl
220
^CTCr&HlFAS
: f CZ-8BM2
230
OUT CTC+0,3:
1 チヤンネル 0 RESET
240
OUT CTC+1,3:
• チヤンネル 1RESET
250
OUT CTC+2,3:
,チヤンネル 2 RESET
260
OUT CTC+3,3:
,チヤンネル 3 RESET
270
»
280
MEM$(&H5E,2)
=HEXCHR$(”13 EF M
) :
7 リコミ TABLE
SET
290
»
300
OUT CTC-f0 t &B100111 :OUT CTC + 0,
30
:• チケンネル 0
SET
310
OUT CTC*f0,&H58
:* ワリコミへ • クトル SET
320
OUT CTC+3.&B1 10001 11:OUT CTC+3,
125
: ,チヤンネル 3
SET
第12章 カラーイメージボード 297
タレ3_ダ
ープもやってしまうのである
第 13 章
テー7もやってレまラの I ある
この章では データレコーダ についてやるのであるが,最初に断っておくと,私はテープ
には未来がないと思っているのである。確かにテープは安価であるし, XI , MZ では信頼
性があってボーレートも まあまあである 0 しかし,いかんせんディスクにはかなうべく
もない。たとえばアセンブラを使おうなどと考えたなら,1バイトの修正に平気で10分以
上かかってしまうのである(もちろんそうでないアセンブラもあるが,その場合はアセン
ブルできるオブジェクトの大きさが制限されたりするのだ)。そのように考えてみるな
ら,私が「う〜む,これはテープのテクニックを極めたとしても,応用は限られてくるな
ぁ」と考えたとしても,もっともな話であろう。
しかしこの世にはまだまだテープユーザーがいることでもあるから,やはりやってしま
うのである。
テ_ブ関係访 I / O アドしス T あ3
早い話が図 U -1 である0
ここで注意が必要なのは, 1 A 01„ 番地の BREAK 信号である。ここはカセットが動作中
に 丨 SHIFT 1+1 break ! (もしくは [ CT ^ rn +同 ) が押されたり,カセット コン トロール
キーが押されたりして動作がその筋したときなどに Low (=0) になるのである 0 よって
ここをチェックしないと,カセットメカが停止しているにもかかわらず,ブログラムの方
はぽかんと口を開けてデータを待っているというだらしないことになってしまうのであ
る。そのようなプログラムはフルロジック コン トロール可能な XI では御法度なのであ
図 13-1 テーブ閫係の I / O アドレス
1 A 01 h (8255 ②ボート B )
300 拭験に出る XI
る。心得ていただきたい。
あと言っておくべきこととなると,サブ CPU のことがあるが,詳しくは第4章を見てい
ただきたい。
0と 1 T あ3
図 13-2 を見ていただきたい。これらが XI のテープにおける0と1である。0と1が記
録できるなら,デジタルデータに限れば充分に戦闘可能になる0実際にはこれらのほかに
0でも1でもないものもあるわけだが,それらは単なる「無記録部分」として扱われる。
図 13-2 「〇」と「しの信号
I I- … 〇
K -125// S -+-125// S-H
250/iS +- ^50//S H
-"時問
では具体的に〇,1を書く方法と読む方法を示すことにする。
まずは書く方である。図 13-2 に示すような信号をテープに記録するわけだから,適当に
タイミングを取って「カセツトテープへの書き込み データ」 を L — H — L にしてやればよ
いのである。
次に読む方である。方法はいくらでも考えられるが,主流は,
1) 信号の立ち上がり (L — H ) をとらえる
2) 185パ s 待つ
3) 信号を読み取って L なら0, H なら1
という手法である。読者の中には「立ち上がりから立ち下がりまでの時間を計ってもいい
じゃないか」と考える人もいるだろうが,それはいけないのである。なぜかというと,そ
れだとノイズを拾う確率がどど一んと増えてしまうからである。 r 1回のサンプリング当
たりの平均エラーレートがこれこれだとすると,〇と1を読み間違う確率があ一たらこ一
たら」というよ一なことは,若干なのでやめておくが,先程述べた主流の方法で世の中が
丸く収まっているのだから,とりあえずはこれでい一のだ。しかし,広い世の中には「うん
にゃ!私はテープリードエラーで痛い目を見たことがある。読むアルゴリズムを変えれ
ば,あのときのブログラムを回収できるかもしれない!」などと言う人もいるかもしれな
い。確かにそのと一りであろう。この本は,そのよ一な人が自力で問題を解決するとい
う基本姿勢を保ちつつ,さっさと次に行ってしまうのであった。
第13章データレコーダ^^
テーブ访記錄フォ-*7ットてあ3
「〇」と r 1」をテープに記録することによって,ブログラムやデータを保存するわけで
あるが,やはり世の常としていきなり ファイル 名やデータを書くわけにはいかないのであ
る。なぜならば, テープはどこから読み始められるか分からないので, 「今読んでいるのは
ファイル 名なのか?それともデータの途中なのか?」ということを判別できなければな
らないからである。つまり「はいっ!もうじき 、、ファイル 名"の始まりですよっ!」と
かいう 特別なマークが 必要なのだ。そんなこんなの形式は各機種,各システムで違ってく
るわけであるが, 図 13-3 が一番 大事な XI HuBASIC での フォーマット である。 MZ での
フォーマット も 図 13-4 に示しておいた。これらは 「Oh ! MZ 」’84 年7月号に掲載されてい
たものである。
図 13-3 XI HuBASIC での テー ブ フォーマット
-- T ンフオメーシヨンフロック- h -データブロッウ
図 13-4 MZ での テープ フ オーマ
•ン
インフォメーシヨンブロック
•データ
ブロック I ,
統く
f ,
% 0 9
n
面
Bmn
11000回
■
図には書いてないが,実はまず最初に無録音部が8秒間ある。これはテープのリーダー
の読み飛ばしと, APSS のために必要である。 APSS , 另 ( J 名「一発頭出し」は簡単に言って
しまえば「早送りしながら無録音部を検出して止まる」ということだからである。続いて
インフオメーシヨン部とデータ部が来るわけである。これらの基本的な構造は同じである
からインフオメーシヨン部だけをねつとりと説明する。
インフォメーション 部は図 13-3 に示してあるようなマークから始まる。つまり「1丨が
302 試肤に出る XI
1000個,「0」が40個,また「1」が40個,最後に駄目押しで「1」が1個である。その
後に続くのがインフォメーションの本体であるが,そのバイト数は32バイトと決まってい
る0
さて,そこで r 1バイト」の書き方である。まず1バイトに先立って スタートビットな
るものが書かれる。これは「1」が1回である。なぜこのよ一なものがあるかというと,
やはりこれはテープが宿命的に持つ悲しさと言わざるを得ない。つまり,テープはメカの
回転変動などの影響を受けやすいので,所々に印を入れておかなければならないのだ。た
だしこれを入れるとエラー発生率が下がるというものではなく,エラーの発生を 検知 でき
るというぐらいの役割しかない。それともう一つ,先程述べた マークと 同じパターンがテ
ーブに書かれるということを避ける 意味 もあるだろう。9ビットごとに「1」が来るのだ
から,ファイル名を書いている最中に偶然マークと同じパターン(「0」が続けて20個)
が現れてしまう心配はないのである(こちらの方がもっと大事であろう)。そのよ一な手続
きを経た後に,1バイトを書くのである。書く 順番は第 7ビットからである。
このようにして32バイトのインフォメーションを書いた後に続いて,2バイトのチェッ
クサムがある。これは「チェックサムエラー」を出すためである。図 13-3 にもあるよう
に,これはインフォメーションブロックにある32バイトのデータ中にある「1」の個数で
ある。この値は変態なことに, High , Low の順になっている。つまり「1」が300個 = 12 C „
個だったなら,この2バイトは 01 H , 2 C H の順に並んでいる(インフォメーションの場合は
32バイトだから,最大でも100„であるが)。 Z 80 での通常の2バイト数値とは逆順なのであ
る。
インフォメ ー ション部は最後に「1」が1回書かれて終わる。これはストッブビットと
呼ばれる。
データブロックは,マークが少し違うこと,長さ(バイト数)が不定であることを除け
ばインフォメーションブロックと同じである。データブロックのバイト数はインフォメー
ションブロックの18,19バイト目(「0バイト目」から数える)にあるから,このことを
心得ていれば問題はない。
読んだり書いたりす3勿てあ3
ここからブログラムの解説モードに突入する。
リスト 13-1 はテープのリード/ライトを行なう機械語ブログラム, リスト 13-2 はそのダ
ンブリスト, リスト 13-3 がそれを使っているブログラムである。ただし恐ろしいこと
に,普通では満足できないというその筋の「さが」によって,さまざまな仕掛けがしてあ
るのだ。すなわち,
•ボーレートを自由に設定できる
• G-RAM を使って 64 K バイトを読み書きできる
•フオーマットは MZ か XI を選択できる
となっているのである。その結果として使い方は少々その筋しているが,パターンは限ら
第 13 章 データレコーダ ja ?
MZ or XI
LONG HIGH
LONG LOW
SHORT HIGH
SHORT L
SAMPLING TIME
SKIP
0056
BCBB
BC0C
5B BC23
21 BC17
BC6A
LAST
0000H
C3 BC27
C3 BC4A
C3 BD30
C3 BD47
BE60
0000
00
41
33
ID
0F
2E
05
03E8
0028
0028
0BB8
0014
0014
0020
AF
011A03
ED 79
2121E4
CD BE3F
FCB MARK
1000
40
40
3000
20
20
;BODY MARK
;FCB LENGTH
;WORK AREA
ROUTINE BEGIN 拿拿拿拿拿
BC f C8255
(C) f A
HL t 8676
WAITXX
WRITE HEAD
8255 CONTROLE
WRITE 1 L 1
COUNTER
WRITE 8 SEC GAP
HL f PATWMM
(PATW),HL ;PA
HL.(FCBAD)
DE f (FCBLEN)
IY f ISET
WRITGO : WRITE HEAD
; PATCH!
1A01
1A03
1A02
0072
51ED
0056
50ED
0041
001D
002E
BC00
BC03
BC06
BC09
BC0C
BCOE
FCBAD : DW
BDYLEN : DW
•
FLAG : DB
LONGH : DB
LONGL : DB
SHORTH : DB
SHORT い DB
W185 : DB
AFTERW : DB
•
ISET :
IMARK1:DW
IMARK2 : DW
IMARK3 : DW
•
DSET :
DMARK1:DW
DMARK2 : DW
DMARK3 : DW
#
FCBLEN : DW
SUM : DS
; 寒拿拿拿章 WRITE
WHEAD1 : XOR
LD
OUT
LD
CALL
; DI
LD
LD
LD
LD
LD
CALL
El
RET
21
0100
WBODYl:LD
HL,100H ;WRITE
BODY
CD
BE3F
CALL
•
WAITXX ;WRITE
GAP
21
50ED
* LD
HL.PATWIO
22
BCBB
LD
(PATW) f HL
; PATCH!
21
FF00
LD
HL f 0000 H-100H
; 0FF00H
01
4000
LD
BC,4e 咖
;GRAM
ED
5B BC0E
LD
DE t (BDYLEN)
FD
21 BC1D
LD
IY.DSET
BC27
BC28
BC2B
BC2D
BC30
BC33
BC34
BC37
BC3A
BC3D
BC41
BC4 5
BC48
BC49
BC4A
BC4D
BC50
BC53
BC56
BC59
BC5C
BC60
.Z80
•
.PHASE
0BC00H
t
FMCMT
EQU
1A01H
C8255
EQU
1A03H
TOCMT
•
EQU
1A02H
PATRMM
EQU
0072H
;LD
(HL),D:NOP
PATRIO
•
EQU
51EDH
;OUT
(C),D
PATWMM
EQU
0056H
;LD
D,(HL) : NOP
PATWIO
EQU
50EDH
;IN
D, (C)
ilL
EQU
65
X1S
EQU
29
X1W
EQU
46
4 JUMP TABLES
1
WHEAD :
jp
WHEADl
WBODY :
JP
WBODYl
RHEAD :
JP
RHEAD1
RBODY :
JP
RBODY 1
れているのだからこれでい一のだ。
リスト 13-1 テープ入出カプログラム
L L s SW
11111
0 X X X X X 5
312ADDDB9
F222EFCFC
0 12 3 4 5 6 7 7 9 B D D F 1 3 5
1111111 1111 1112 2 2
ccccccc cccc cccc c C
CQ ^3 ^3 Bfp p*} CO CD
B B B
试験に出る XI
BC64
F3
BC65
CD BC6A
BC68
BC69
FB
C9
BC6A
D9
WRITGO
BC6B
FD 4E 00
BC6E
FD 46 01
BC71
37
BC72
CD BCE3
•
BC75
FD 4E 02
9
BC78
FD 46 03
BC7B
B7
BC7C
CD BCE3
學
BC7F
FD 4E 04
t
BC82
FD 46 05
BC85
37
BC86
CD BCE3
BC89
37
■
1
BC8A
CD BCFB
A
BC8D
D9
t
BC8E
CD BC96
■
BC91
37
t
BC92
CD BCFB
BC95
C9
修
BC96
D9
WBYTES
BC97
21 0000
BC9A
D9
BC9B
CD BCB5
BC9E
D9
•
•
BC9F
7C
BCA0
65
BCA1
6F
BCA2
22 BC25
BCA5
11 0002
BCA8
21 0056
BCAB
22 BCBB
BCAE
21 BC25
BCB1
CD BCB5
BCB4
C9
BC35
D5
WBS1 :
BCB6
78
BCB7
FE 40
BCB9
38 05
BCBB
ED 50
PATW :
BCBD
C3 BCC1
BCC0
56
MRAMW :
BCC1
23
MRAMW1 :
BCC2
03
BCC3
CD BCCD
BCC6
Dl
BCC7
IB
BCC8
7A
BCC9
B3
BCCA
20 E9
BCCC
C9
BCCD
C5
•
ふ BYTE:
BCCE
37
BCCF
CD BCFB
BCD2
06 08
籲
1
BCD4
CB 12
WBYTE1 :
BCD6
D9
BCD7
D2 BCDB
BCDA
23
BCDB
D9
WBYTE2 :
BCDC
CD BCFB
BCDF
10 F3
BCE1
BCE2
Cl
C9
BCE3
F5
WMARK :
DI
CALL WRITGO ;WRITE BODY
El
RET
: EXX
LD
LD
SCF
C,(IY+0)
B バ IY+U
; CARRY=1
CALL
WMARK
;WRITE MARK1
LD
C,(IY+2>
LD
B v (IY+3>
OR
A
; CARRY=0
CALL
WMARK
••WRITE MARK2
LD
LD
SCF
C,(IY+4)
B,(IY+5>
; CARRY=1
CALL
WMARK
;WRITE MARK3
SCF
; CARRY=1
CALL
WBIT
;START BIT
EXX
CALL
WBYTES
;HONTAI
SCF
; CARRY:1
CALL
WBIT
;STOP BIT
RET
: EXX
LD
HL f 000OH ;CHECK SUM
EXX
CALL
WBSl
EXX
LD
A,H
LD
h 9 l
LD
L, A
••SWAP
H-L
LD
(SUM) t HL
LD
DE f 2
LD
HL f PATWMM
LD
< PATW) f
HL
; PATCH!
LD
HL f SUM
CALL
WBSl
;WRITE CHECK SUM
RET
PUSH
LD
DE
A f B
CP
40H
;BC <
4000H ?
JR
C,MRAMW
••THEN
JUMP
IN
D f (C)
;GET FROM GRAM
JP
MRAMW 1
LD
D f (HL)
;GET FROM MRAM
INC
HL
INC
BC
: INC POINTERS
CALL
WBYTE
;WRITE 1 BYTE
POP
DE
DEC
DE
••DEC COUNTER
LD
A,D
OR
E
: CHECK IT
JR
NZ.WBSl
RET
PUSH
BC
;WRITE 1 BYTE
SCF
CALL
WBIT
LD
RL
B,8
D
;8 BITS
EXX
JP
NC f WBYTE2
INC
HL
;INC CHECK SUM
EXX
CALL
WBIT
;WRITE 1 BIT
DJNZ
WBYTE1
POP
BC
RET
PUSH
AF
••SAVE CARRY
第 13 章 于ータレコーダ 305
(C) f A
AF
WAITX
A
(C) f A
12
AF f AF f
4
WAITX
17
BC t FMCMT
10
A, (C)
12
4
NC,BREAK
10
BC
10
10
A f (FLAG);GET FLAG
A f 00H
;IF MZ CY REVERSE
AF
BC
WBIT
BC
BC
A t B
C ;COUNTER
Z,WMARK2
AF
WMARK1
AF
AF
1 if f NON CY_>”0
BC
11
NC f WBITO
12 or 7
A,(LONGL)
13
AF f AF f
4
A, 《 LONGH )
13
WBIT1
12
C.WBITl
12 or 7
A 9 (SHORT い
13
AF f AF 1
4
A t (SHORTH)
13
WBIT1
12
BC f C8255
10
AF
11
A f 1
7
; 拿拿拿拿拿
t
WRITE
d c a n i
ROUTINE END ttttt
I HP T k? t? D 1?/^ T k ! 脅會會會曹
F3
§ ♦ ♦ ♦ ♦ ♦
RHEAD1 :
Kb AL/ r
DI
: READ HEAD
21
0072
LD
HL f PATRMM
22
BDC6
LD
(PATR) t HL
;PATCH!
2A
BC0C
LD
HL f (FCBAD)
;DCB ADD.
ED
5B BC23
LD
DE,(FCBLEN)
;LENGTH
FD
21 BC17
LD
IY f ISET
CD
BD61
CALL
READGO
FB
C9
#
El
RET
F3
RBODY1 :
DI
••READ BODY
21
51ED
LD
HL.PATRIO
22
BDC6
LD
(PATR) f HL
; PATCH!
21
FF00
LD
HL f 0000H-100H
;DATA ADD.
01
4000
LD
BC t 4000H
ED
5B BC0E
LD
DE f (BDYLEN)
;LENGTH
FD
21 BC1D
LD
IY f DSET
CD
BD61
CALL
READGO
FB
C9
•
El
RET
D9
READGO :
EXX
CD
BDFD
REDGOl :
CALL
COUNT0 ;COUNT
•ず
FD
5E 02
LD
LD
E f (IY42)
FD
56 03
D,<IY+3>
B7
OR
A
ED
52
SBC
HL,DE ;CHECK
MARK2
20
F2
JR
NZ,REDGOl
3A BC10
CE 00
IF
F5
C5
CD BCFB
Cl
0B
78
B1
28 03
FI
18 F2
WMARK1
FI
FI
C9
WMARK2
WBIT :
C5
30 09
3A BC12
08
3A BC11
18 0B
38 09
3A BC14
08
3A BC13
18 00
011A03
F5
3E 01
WBIT0
WBIT1
ED 79
FI
CD BE52
AF
ED 79
08
LD
ADC
RRA
PUSH
PUSH
CALL
POP
DEC
LD
OR
JR
POP
JR
POP
POP
RET
; CY -:
PUSH
JR
LD
EX
LD
JR
JR
LD
EX
LD
JR
LD
PUSH
LD
OUT
POP
CALL
XOR
OUT
EX
CALL
LD
IN
RRCA
JP
POP
RET
BCE4
BCE7
BCE9
BCEA
BCEB
BCEC
BCEF
BCF0
BCF1
BCF2
BCF3
BCF5
BCF6
BCF8
BCF9
BCFA
BCFB
BCFB
BCFC
BCFE
BD01
BD02
BD05
BD07
BD09
BDOC
BD0D
BD10
BD12
BD15
BD16
BD18
BD1A
BD1B
BD1E
BD1F
BD21
BD22
BD25
BD28
BD2A
BD2B
BD2E
BD2F
BD30
BD31
BD34
BD37
BD3A
BD3E
BD42
BD45
BD46
BD47
BD48
BD4B
BD4E
BD51
BD54
BD58
BD5C
BD5F
BD60
BD61
BD62
BD65
BD68
BD6B
BD6C
BD6E
2 0 7
1114
21 D
5 0 0
E A 8 E
B 1 7 B
D 1 D F 219
c 0 E 0 D c c
306 拭験に出る XI
BDBD
D5
RBSl:
BDBE
CD BDD5
BDC1
78
BDC2
FE 40
BDC4
38 05
BDC6
ED 51
PATH :
BDC8
C3 BDCC
BDCB
72
MRAMR :
BDCC
23
MRAMR1 :
BDCD
03
BDCE
D1
BDCF
IB
BDD0
7A
BDD1
B3
BDD2
20 E9
BDD4
C9
00
08
LD
LD
D f 00H ;CLEAR DATA
B f 8
BE 14
RBYTE1:
CALL
EXX
RBIT
01
JR
NC.RBYTE2
INC
HL : INC CHECK SUM
RBYTE2:
BXX
12
RL
D ;STORE 1 BIT
F4
DJNZ
RBYTE1
POP
BC
RET
BXX
PUSH
HL
0002
LD
DE t 2
0072
LD
HL f PATRMM
BDC6
LD
(PATH) f HL
; PATCH!
BC25
LD
HL t SUM
BDBD
CALL
RBSl : READ
CHECK SUM
POP
H し
RET
DE
RBYTE
A f B
40H ;BC < 4000H ?
C f MRAMR ;THEN JUMP
(C > , D ;STORE TO GRAM
MRAMR1
(HL) t D ;STORE TO MRAM
HL
BC
DE
DE
A f D
E ;CHECK COUNTER
NZ f RBSl
BDDB
BDDD
BDDF
BDE2
BDE3
BDE5
BDE6
BDE7
BDE9
BDEB
BDEC
BDAA
BDAB
BDAC
BDAF
BDB2
BDB5
BDB8
BDBB
BDBC
BDED
BDF0
21 0000
3A BC10
COUNT1 : LD
LD
HL f 0000H
A.(FLAG)
BDD5
C5
•
RBYTE : PUSH
BC : READ 1
l BYTE
BDD6
CD BE14
CALL
RBIT
BDD9
30 32
JR
NC.BREAK
: START BIT
BD70
FD 46 04
LD
B,(IY+4>
BD73
05
DEC
B
BD74
3 A BC10
LD
LD
A f (FLAG)
BD77
57
D t A
BD78
CD BE14
REDG02 :
CALL
RBIT
BD7B
3E 00
LD
A f 00H
BD7D
17
RLA
; X1->1 f MZ->0
BD7E
BA
CP
JP
D ;BIT = FLAG
BD7F
CA BE0D
Z,BREAK ;THEN BREAK
BD82
10 F4
•
DJNZ
REDG02
BD84
CD BE14
•
CALL
RBIT ;READ LAST M
BD87
D2 BD62
•
JP
NC.REDGOl
BD8A
D9
•
EXX
BD8B
CD BDA2
•
CALL
RBYTES ;READ HONTAI
BD8E
ED 5B BC25
t
LD
DE,(SUM)
BD92
7A
LD
A f D
BD93
53
LD
D t E
BD94
5F
LD
E,A ;SWAP H-L
BD95
B7
OR
A
BD96
ED 52
SBC
HL f DE ;CHECK SUM
BD98
C2 BE11
•
jp
NZ.CSERR
BD9B
CD BE14
•
CALL
RBIT : STOP BIT
BD9E
D2 BE0D
•
JP
NC,BREAK
BDA1
C9
•
•
RET
BDA2
D9
RBYTES :
EXX
BDA3
21 0000
LD
HL.0000H ;CHECK SUM
BDA6
D9
EXX
BDA7
CD BDBD
CALL
RBS1
••READ HONTAI
PUSCALLDCPJROUJPLDINIIN'PODE'LDORJRRE*
T
c c p c
66D9039B019
10CD32DC1CC
951121 D19
DE1222CEC
第 13 章データレコーダぶ? 7
BE20
BR22
BE23
BE26
BE27
ED 78
0F
D2 BE0D
0F
D2 BE20
HBIT2
BE2A
BE2D
BE30
BE32
BE33
BE36
BE37
BE3A
BE3D
BE3E
3A BC15
CD BE52
ED 78
0F
D2 BK0D
0F
3A BC16
DC BE52
Cl
C9
BE3F
BE42
BE44
BE45
BE48
BE49
BE4C
BE4D
BE4E
BE4F
BE51
BE52
BE53
BE54
BE57
BE58
011A01
ED 78
0F
D2 BE0D
AF
CD BE52
2B
7C
B5
20 FI
C9
IN
RRCA
JP
RRCA
JP
A f (C)
NC,BREAK
NC,RBIT2
12
4
10
4
10
: WHILE(LOW) DO
••NOW
GOT 1 EDGE 1 !
LD A,(W185)
CALL WAITX
IN A,(C)
RRCA
JP NC,BREAK
RRCA
LD A,(AFTERW)
CALL C,WAITX
POP BC
RET
READ ROUTINE END 拿拿
ttttt WAIT ROUTINE
SKIP TIME
WAPSS :
LD
BC,FMCMT;10
IN
A,(C) ;12
RRCA
;4
JP
NC f BREAK;10
XOR
A ;4
CALL
WAITX ;17 +
DEC
HL ;6
LD
A f H ;4
OR
L ;4
JR
NZ,WAPSS ;12
RET
: 10
F5
: DAITAI
WAITX :
HL 拿 3688
PUSH
AF
;11
3D
WAITXL :
DEC
A
;4
C2 BE53
•
jp
NZ,WAITXL
;10
FI
C9
t
POP
AF
;10
RET
; 1 1 + 14 拿 Acc + 20
;10
; Acc=46 -
>644+31:
:675
MACRO-80 3.44
09-Dec-81
PAGE
-7
0000
COUNT0 :
LD
HL f 0000H
BC10
LD
A f (FLAG)
OR
A
F0
JR
NZ f CTl1
BE14
CT01 :
CALL
RBIT
RET
INC
Sl
F9
JR
CT01
BDFD
BE00
BE03
BE04
BE06
BE09
BE0A
BE0B
RBIT :
RBIT1 :
PUSH
LD
IN
RRCA
JR
RRCA
JR
BC
BC f FMCMT
A,(C) ;IN DATA
NC,BREAK
C f RBIT1;WHILE(HIGH> DO
BE0D
3E ID
BREAK :
LD
JP
A,29
;ERR CODE
BE0F
DD E9
(IX)
BE11
AF
CSERR :
XOH
A
UNPRINTABLE
BE12
DD E9
JP
(IX)
BDF3
BDF4
BDF6
BDF9
BDFA
BDFB
B7
20 10
CD BE14
D0
23
18 F9
CT1
OR
JR
CALL
RET
INC
JR
A
NZ f CT01
RBIT
NC
HL
CT11
;IF MZ COUNT0
1A70D838
23B2CD21
0
A 8 0 8
17 F p
5 1 D F 0 F 8
c 0 E 0 3 0 3
4 5 8 A B D E
1111111
E E E B E E E
B B B B B B B
BE59
BE60
LAST :
DS
DS
END
0
48
C0
C0
Cl
Cl
C2
C2
C3
C3
C4
C4
C5
C5
C6
C6
C7
C7
33 66 5E E9 DC 9D A9B4
SUM
00
C6 BD
F4 CD
CD A2
53 5F B7 ED
CD 14 BE D2
21 00 00 D9
E511 02 00
25
ープ入出カダンプ
4DA82EA1E010
1D1FDB30B2F0
DD18F2F9D5E0
cl 03050 C0BB0
0E1FEDE12C30
F300BCBCD750
0950DCDEFB20
2FCF0B0B02C0
789025228 ED0
B1E3D1D57B30
C3DFFAFCD250
B2D003ODE5F0
08F88E8CAD90
IDA 7 7 B7B1CC0
AE9DD0D61F19
3BEEE2E10AFC
5 0
8C1DA9A1
3B0E1C22
B3EF11DD
013A0CBF
8A5E1E6C
13FB0BCB
C8A2ED23
B015B 022
1C3D220B
1B0C5D05
A411DF2D
310 FC07E
8A 0988 1C
0307072 B
C98D9D3C
B01E7EF0
08080808
00112233
DDDDDDDD
B B B B
361C05ECBD20E122
E 92702 FB1CD1CCF1
DD 992181179 CCC8A
CCDD 027 CD3DBBB13
799C1C 53 C52B0B19
3DCB1BDCBC1F1FF0
5CC5CB90D9BDAD30
0BBBBBC5CCCC3C03
6BBD52CDD 9895585
4FFC22BECE0DFC2C
DDD 9205530639519
FCCD20B 00202 CFBC
4770F6D 833 CC 1 F 81
033065 C32BBBC17F
ECC051C06ABB30B1
4BB062B457FDF00F
30CB227A
F0BF0F5C
91EDE0CA
C20B52BB
BDB1D207
FB56F511
D6DDDDA0
BCECBE30
120CD75E
624BFB03
D10DD34E
C501C00B
CD119664
BE02D541
71FD9DDD
12FFCFFC
A E 2 F 3 2
5 A 0 3 D F
6 A 9 c 8 0 9
c 5 4 2 0 B c
B 0
c 0
D1D890D0
EDC0D0C0
53563101
00 c 02212
83901909
32C00C2F
DED0294C3
BFB23DFB2
EDC19D0D8C30E000
BBB1CB0B7CB3B11D
D252ED2DD3AE42AK
062 CBB7CBC7B113B
552D6F98
725D85A7
0C3F7C98E05131E3
46002616 EDA1ACCE
14BD
22BA7A 640082 DB 16
6AB21A5DAB15D2F6
0 0 8 4
3 0 E 1
F 12 3
A 2 2 2
CE0CC62D
BB0BB40F
305BA40BAF1EADEC
C0001E 0563206 F4B
CEE8A16DDDCBD0D3
BB2B125ECCB5C0FE
A0F 0091 CC1BD3ECD
4600072 BB0BEF4BC
3DD80D3C7020CD37
CB122EF 01024 BFEB
C7300AEA1100D9D3
B43001B 222501 DC0
731843 FCD9D11976
2C 42103 BFCE02C34
3D0301DBCB1FDB1D
CB00O0CBBF2FFF0F
290 f MEM$(&HBC20 f 5) =HEXCHR$ ( ff 00 14 00 80 00")
300 1
310 , for MZ-80K/C/1200/700/1500:1200 本 •-
320 , MEM$(&HBC10 l 16)=HEXCHR$( tf 0183 813E 3C 5A 05 F0 55 28 00 28 00 F8 2A 14">
330 f MEM$(&HBC20 f 5) =HEXCHR$ ( f, 00 14 00 80 00 tf )
340 1
350 INPUT ,f R/W M ;A$:IF A$ = ff R tf THEN GOSUB•• READGOTO 350
360 IF A$ = fl W ff THEN GOSUB fl WRITB w :GOTO 350
370 GOTO 350
380 1
390 LABEL ,f READ tf
400 CMT = 2: 1 PLAY
410 D$ = USR2( fttf ) : 1 READ FCB
420 CMT=1 ゾ CSTOP
430 PRINT #0 "FOUND" ,MEM$UHBE61•16 > ,
440 L=CVI(MEM$(&HBE60^18 f 2)) : 1 LENGTH
450 S=CVI(MEM$(&HBE604 20 f 2)) : 1 START ADDRESS
460 X=CVI(MEM$(&HBE60 + 22 f 2)) : 1 JUMP ADDRESS
470 PRINT #0 RIGHTS ( tf 000 ff + HEXS (S) f 4) f
480 PRINT «0 RIGHTS ( f, 000 tf -fHEX$(S4L-l) f 4 ) f
490 PRINT #0 RIGHTS ( H 000 ff + HEX$(X) f 4 )
500 1
510 MEM$(&HBC0E f 2)=MEM5(&HBE60^18 f 2): 1 COPY LENGTH
520 CMT=2: f PLAY
530 PRINT #0 "LOADING” ,MEM$UHBE61•16 >
540 D$=USR3( MH ) : f READ BODY
550 CMT=1 • ノ CSTOP
560 RETURN
570 f
580 LABBL ft WRITE tf
590 PRINT #0 "WRITING 11 f MEM$(&HBE61 f 16)
600 CMT=10:•WRITE
610 D$ = USR0( ,tff ) : 1 WRITE FCB
620 CMT=1: f CSTOP
630 *
640 MEM$(&HBC0E f 2)=MEM$(&HBE60>18 f 2) : f COPY LENGTH
650 CMT=10:•PLAY
660 D$ = USRl( fttf ) : 1 WRITE BODY
670 CMT=1 : f CSTOP
680 RETURN
では機械語ブログラムは後にして,先にリスト 13-3 の使い方を説明する。
よくある展開として,各モードの指定は 「 MEM $ J で機械語ルーチンにパラメータを渡
すことで行なっている。一番最初に指定してあるのは XI フォーマッ トの場合のパラメ ー
夕である。大抵の用はこれで済むだろうが,それだけでは面白くないので,後に続くよう
にさまざまなボーレ ー トと フォーマッ トの挑戦を受けているのである。使うときは REM
(’) を適当に入れたり消したりしていただきたい。
パラメータの領域は BC 10„ 〜 BC 24„ になって いる。それぞれの意味は表 13-1 に 示して
ある。この部分はリスト 13-1 と併せて見た方が分かりやすいだろう。
それはともかく,このリスト 13-3 は 30 K バイト以上の長さのファイル(実は BASIC )
を読み書きさせて試験してあるので,異機種のフォーマットも大丈夫のはずである。ただ
し1200 bps だけは例外で, CZ -8 RL 1 を使った場合は, 背面にあるボーレート切り換えスイ
ッチを Low にしておけば OK だが,それ以外の内蔵デッキでは,かなりエラーが出てしま
うようである。ちなみに私は,しばらくの間このポーレート切り換えスイッチに気が付か
ず,バグ地獄をはいずり回っていたのであった。
それはさておき,具体的な説明をしておく。110〜140行に DEFUSR 文が4個並んでい
る。機能は注釈にあるとおりである。まずは390行からのテープリードであるが,最初に
CMT 命令でカセットデッキを READ 状態にしている。ブログラム作成中は機械語ルーチ
ンの中にカセツトデツキコントロールのためのサブルーチンも入れてあったのだが,ちょ
310 試験に出る XI
表 13-1 リスト1のパラメータの説明
BC 10 h = フラグである。0なら XI フォーマット,1なら MZ フォーマット。
BC 11 h = T の High の長さ。ウェイトルーチンに渡すパラメータである。
BC 12 h = _ T の Low の長さ。
BC 13 h = ’CT の High の長さ。
BC 14 h = ’0" の Low の長さ。
BC 15 h = 信号の立ち上がりからサンプリングまでの待ち時間( XI では185郎)。
BC 16 h =,1 •を読んだ後のスキップ時間(あんまりたいした意味はない)。
BC 17, 8h = インフォメーションブロック ( FCB ) の最初のマークの数。
BC 19, Ah =インフォメーションブロックの2番目のマークの数。
BC 1 B , Ch = インフォメーションブロックの3番目のマークの数。
BC 1 D , Eh = データブロックの最初のマークの数,
BC 1 F , 20 h = データブロックの2番目のマークの数。
BC 21, 2 h = データブロックの3番目のマークの数。
BC 23, 4 h = インフォメーシヨンブロックの長さ。
っと長いし,第4章でやったサブ CPU の使い方そのものなので,取り除いてしまったので
ある。次に来るのは 「 USR 2 (、、つ」で,これはインフォメーションブロックの読み込み
である。読み込む 位置 (アドレス)は BC 0 C „ からの2バイトに入っていることになってい
る。何もいじらなければここには BE 60 H が入っているので,モニタでダンプすれば見るこ
とができるのである。読み込み終わったなら,一旦テープを止めて ( CMT =1) ファイル
名を表示する。時々ファイル名の中に変なコントロールコードが交じっていることがある
ので , 「PRINT #0」を使っている0ここではさらに 縁起 ものなのでスタートアドレ
ス,エンドアドレス,実行アドレスも表示している0
次に 「 USR 3 (、、")」でファイルの本体を読み込むわけであるが,ここで先程言ってお
いた 長さが 出てくる。長さは BC 0 E „ からの2バイトで指定するのだ0サンプルブログラム
では常識どおりにインフォメーションブロックの18,19バイト目を使っている0
ファイルの本体は無条件に G - RAM の400 0 H (青 画面)からにロードされるので,ボー
レートが目で見えるのである。 48 K バイト ( C 000 H バイト)を超える場合は,メイン RAM
の BF 00„ 〜 FEFF „ にロー ドされる。なぜそのように中途半端なアドレスなのかという
と, XI の HuBASIC では FF 00„ 〜を勝手に使えないからなのである。このことを一番 手軽
に確認するには,モニタに入ってダンプコマンドを実行してみればよい0しっかりキー入
カバッファに使われてしまっているのである。てなわけで,使用に当たってはご注意であ
る 0
次は580行からのファイルの書き込みであるが,これは似たよ一なものであるから割愛
してしまって,さっさとリスト 13-1 の説明に行ってしまう。
まずは 「 PATRMM 」 というやっを見ていただきたい。察しのいい人なら分かるよ 一
に, これはパッチ用のデータである。すなわち,このブログラムは自分自身を書き換える
のである。 嫌いなテクニックを 使ってしまって 最高に 気分が悪い私である。なんでこ一
なってしまったのかとゆ 一と,インフォメーション ブロックやチェックサムは メイン
RAM ヘリー ド(もしくは メイン RAM からライト)しなければならないが,データブロッ
第13章データレコーダ
クは無条件に G - RAM を対象にしているからである。フラグを使って分岐するとタイミン
グがその筋する可能性が高いのだ。ソフトウェアでタイミングを取っているブログラムの
泣き所である。〜 MM というのがメイン RAM 用のパッチ,〜10というのが G - RAM 用
のパッチである。
プログラムの実体は四つのジャンプから始まる。その次にパラメータェリアが 並ぶ。 で
は本筋の BC 27 h O rWHEADlJ を説明する。最初にやっているのは APSS 用の8秒間の
ブランクの書き込みである0 8255のビットセット/リセットコマンドを使っていることに
注意。詳しくは第0章の8255②の所を見ていただきたい。 「 WAITXX 」 というサブルーチ
ンは,前述の 「 BREAK 信号」のチェックも行なうウェイトルーチンである。それが済ん
だ後にインフォメーションブロックを書き始めることになる。ソフトウェアでタイミング
を取るプログラムであるから BC 33„ 番地の 「 DI 」 で割り込みを禁止していることに注
.目0次に,インフォメーションブロック用のデータはメイン ram 上にあるので, BC 34„ 〜
BC 39„ でパッチを行なっている。これによって 「 PATW 」( BCBB „) からの2バイトが,
LD (HL), D
N 0 P
に書き換わる0ここまできたなら,あとは HL レジスタにインフォメーションブロックの
データのアドレスを入れ ( G - RAM の内容を書く場合は BC レジスタ), DE レジスタにそ
の長さを入れ, IY レジスタにマークの長さ ( 3種類分)へのポインタを入れて 「 WRITG 0」
を CALL するわけである。
BC 4 A „ 番地からの 「 WB 0 DY 1」 も基本的には同じである。
最初にやっているのは GAP の畜き込みである〇インフォメーションブロックの直後に
データを書き込むと,タコなリードルーチンが読み飛ばしてしまうかもしれないので入れ
てある。本式にはど一するのか知らないが,世の中は丸く収まっているよ一である。その
後は G - RAM 方面へのパッチを行なって,各レジスタに値を放り込んで, 「 WRITG 0 J を
CALL しているだけである。
以上のように害くと実に簡単そうに思えるかもしれないが,ここから先が七面倒な ので
ぁる0
BC 6 A „ からの rWRITGOJ を見ていただきたい。3回 「 WMARK 」 を呼んでマークを
害いている。このサブルーチンは キャリー フラグがセットされているなら「1」を,リセ
ッ トされているのなら「〇」を, BC レジスタの数だけ書くのである。ただしこれは XI フ
ォー マッ トの場合である0例の BC 10 H 番地のフラグが1 (MZ モード)のときは「〇」,「1」
が逆になる0 BCE 4„ 番地あたりを見て納得していただきたい。その後はフォーマットどお
りにスタートビットを書き,本体のバイト列を書き ( BC 8 E H の 「CALL WBYTES 」), 最後
にストッブビットを書いている。
そこで問題点は BC 96„ 番地の 「 WBYTES 」 に移る。まず典レジスタの HL を0000 „ にし
ている。これはチェックサム用のカウンタである。その後下働きの 「 WBS 1」 を呼び出して
いる 0 これがバイト列ライトの直接の実行者である。このルーチンから帰ってきた後はま
た 「 WBS 1」 を呼び出して2バイトのチェックサムを書いて終わりである。
312 試験に出る XI
「 WBS 1」( BCB 5„) はスタートビットとして「1」を1回書いた後 ( BCCE H 〜
BCDIh ), データを1バイトずつ D レジスタに取り出して 「 WBYTE 」 を使って第7ビッ
卜から順に書いている(各バイトごとに各スタートビットも入れれば,1バイトごとに9
ビット書いているわけだ)。 「 WBYTE 」 はチェックサム用に, BCDA „ 番地で「1」を数え
ている。
ここでやっと 「 WBIT 」( BCFB „) の説明に達した。このルーチンはキャリーフラグがセ
ッ トされていれば「1」を,リセ ッ トされていれば「0」を書くわけで ある。 BCFC „ から
BD 11„ までの間でその判定をして, A , A ' レジスタにウェイト用の値を入れている。
BD 10„ の無駄な 「 JR 」 は,「1」と「0」での時間差をなくするためのもので縁起ものなの
で入れて ある。 念のために言っておくが, 「 1 」 は別名を 「 LONG 」, 「 0 」 は別名を 「 SHORT 」
とも言うので ある。 つまり波形の長さからきた呼び方で ある。
「1」,「0」 の書き方は少し考えれば分かる ように, たとえば XI で 「1」 を書く場合
は, I / O の 1 A 02 H 番地の第0ビットをセット ( High ) して250 // s の間待ち,その後そのビ
ットをリセット ( Low ) して250 // s 待つのである(プログラムでは8255のビットセット/
リセットコマンドを使っている)〇
実を言うと, XI の場合はリセット ( Low ) しておく時間は少々短くしてある。理由
は,このサブルーチンからリターンして 次の 1 ビッ トを害き始めるまでの間 も Low を 書
き続けているから,このサブルーチンの中でまるまる250 // s 待っていると, Low の期間が
長くなりすぎてしまうからなのだ。この点に気を付けないと, XI ではリードェラーがバシ
バシ起きてしまうようである0しかし MZ の方はこの点に関してはのんびりしているらし
く, Low が長すぎても問題はないようである。
BD 25„〜 BD 2 D „ は 「 BREAK 信号」のセンスである。この分の時間も Low の長さに入れ
てやらなければならないので, ( LONGL ) と ( SHORTL ) の値はその分小さくなってい
る。あ〜めんどくさ。
以上で テ ー ブライ トルーチンの説明を終わるが,なぜか MZ フォーマッ トは2回セーブ
のはずなのにそうなっていない。これを手抜きというのである。それはともかく,ここま
で読んで気が付くように,この ブロ グラムは あんまり面白くない (作った本人が言って
いるのだから本当である)。ほとんど唯一の特長は,わりかしきっちりしたトッブダウンに
なっていることぐらいである。この事態を招いたもとは,テープの リード/ライ トルーチン
というものは,決まりきったことを決まりきったようにやるものだからということであろ
う。「可能な限りに短く作る」などの目標があればまた別なのだろ一が。
と,グチをこぼしながらリードルーチンの説明に入る。 BD 30 H からである。
「 RHEAD 1」,「 RBODY 1」 の構造は基本的にライトルーチンと同じである。最初に マーク
を検出するのであるが,ここでは1番目のマークははなから無視している。理由は,
「2,3番目のマークだけで充分だから」と 「 MZ ではテープのリーダー部分のせいで,1
番目のマークは決まった個数にならないから」である。繰り返すが,世の中は丸く収まっ
ているのである。
というわけで,2番,3番目のマークを目標にして 同期を 取って 実際のデータが書かれ
第13章データレコーダ
ている所に迫っていくのが BD 62 H 〜 BD 89 H T ある。ここまできたなら, 「 RBYTES 」 を呼
び出して,指定したバイト数を読んでしまう。その後はチヱックサムを確かめて,合って
いれば 0 K , さもなければエラーである。
「 RBYTES 」,「 RBS 1」,「 RBYTE 」 に関しては別に説明する必要はないだろう,という
ことで BE 14 H 番地からの 「 RBIT 」 である。
まず, BE 18„〜 BE 1 F „ のループである。ここは「テープから読んだ信号が High である限
りループせよ」= 「 Low になったら出ていいよ」ということである ( BREAK 信号のチ エッ
クは別だよ)。ここを抜けてきたならば,そのときテープの信号は Low になっている。次
にある BE 20 H 〜 BE 29 H のループは「テープから読んだ信号が Low である限りループせ
よ」= 「 High になったら出ていいよ」である。これら二つのループのやっていること
は,
エッジの 検出
なわけである。すなわち,テープの信号が Low — High になった直後には BE 2 A „ 番地に
来ているのである。そこで,( XI の場合は)185 // S 待ってからもう一度テープの信号を読
み取り,「1」なのか「0」なのかを見分けるのである。これがテープリードである。
プログラムでは BE 37„. 地から,
LD A ,( AFTERW )
CALL C,WAITX
などというものがある。これは,「1」を読んだ後は,( XI の場合なら)次の1ビットまで
500—185 = 315 // s も時間があり,へたをするとよけいなノイズを読んでしまうかもしれな
いので厄除けのつもりで入れたのだが,はっきり言ってほとんど役に立っていないよ一で
ある0 6バイト損こいた。なお,ライトルーチンと同じよ一に , MZ フォー マットを読むと
きも二度読みはしていない。
そのよ一なわけでブログラムの説明は一段落するのであるが,ここで一般教養として ソ
フトウヱアでタイミ ングを取る場合に必要な「時間の計算方法」を示して おく 0
てきと一な機械語の参考書を見ると,各命令ごとに 「T (ステート 数)= XX 」 という数
字が書いてあるはずである。これが,「その命令を実行するのに何クロック必要か」という
ことである。たとえば , 「LD A , n 」 ならば T = 7であるから,7クロックかかるのであ
る。そいでもって, XI のクロックは 4 MHz = 4000000 Hz だから,1クロックの時間は,
1 -r 4000000 ( Hz ) =0.00000025 (秒)
となる。すなわち1クロック =250 ns = 0.25;/ s である。このことから , 「LD A , n 」 の実
行時間は 0.25(# s)x 7=1.75(# s ) と計算できる。実用的には, すべてのステ ー ト数を 足し
合わせた 数字を 4で 割り, それに [ MS ] を 付ければよい0
念のために書いておくと,
lms (ミリ秒) =0.001 秒
1 //S (マイクロ秒) =0.000001 秒
Ins (ナノ秒) =0.000000001 秒
である。
3 U 試験に出る XI
そのよ一なわけでテープであった0本章のサンプルプログラムは,このままでは単なる
BASIC テープをバックアップするぐらいのことしかできない。しかし頑張れば「テープ—
フロッピーディスク転送ブログラム」ぐらいにはなるだろう。また, G - RAM にロードさ
れたプログラムをメイン RAM に転送して実行する機械語ルーチンなどもおいしそうで
ぁる。
最後に言っておくが,このブログラムは プロテクトのかかったゲームプログラムなどは
読めない。 読めないったら読めない。まかり間違っても「某ゲームのテープ版を読めない
んですけど,バグじゃないですか」などという文句をつけてこないよ一に。ボーレートを
自由に変えれる所まではやったのだから,その先の 「不毛なあの筋」は自由研究であ
る。
第 13 章 データレコーダ J75
turboZ
Z の機能はおいしいのである
■第 14 章
nz の機能は劣いレいの I ある • • • •
この章では turboZ の機能についてやるのである。さっさと書いてしまうと,
turbo ( turbo II も含む)と turboZ の差は,
1 ) アナログ RGB にも対応し4096色を使用可能
2) 各種モード付きの画像取り込み機能
3) 第2水準 ROM を標準搭載
4) 2 HD ドライブ搭載
5) グラフィック2画面をブライオリティ付きで重ね合わせ表示可能
6) テキストパレットを使用可能
7) FM 音源を標準で搭載
8) マウスを標準装備
9) スクロールイン/アウト機能
10) インタレ ー ススーパーインポーズ
11) クロマキ ー (画面合成)可能
などとなっている。
なお, turbo と turboZ の間には turbolll という微妙に緊張した関係のマシンもある
が,それについては自由研究としておく。
さて,以上のことをつらつら考えるに, turboZ にあって turbo にない機能というの
は,ただただひたすらに画面周りだけなのである。付けようと思えば 2 HD ドライブだろう
が, FM 音源だろうが,第2水準 ROM だろうが付いてしまうのである。そこで,「グラフ
ィック J , 「画像取り込み」,「画面コントロール」の3点に絞って取りあげることにした0
ただし,これらはそれぞれ微妙に絡みあっており,決してバラバラに独立したものではな
いということを断っておく。またこれ以降のブログラムは CZ -8 FB 02 を使うこと。
7ラフィックてあ3
CZ -8 FB 03 を使えばちょいちょいと4096色が使えるのだが,昔ながらの CZ -8 FB 02 だ
となかなかそうはいかない。そこでリスト 14-1 である。これは4096色の色見本である。
グラフィック画面は 320 X 200 であるから,全部で64000ドットなわけだ。それを4096の
色数で公平に配給すると,1色当たり 15.625 ということになる。よってあれこれ考え
て,1色当たり縦3ドット x 横4ドットの12ドットを,さらに縦横64色ずつ並べること
にした。その処理をしているのが250〜400行である。カラーコードの並び方は,画面左上
から右にかけて順に0,1, 2, 3, 4,……,63となり,一段下がって左から64,
65, 66……という,ごく当たり前の配列になっている。で,おそらくは読者の中にはど一
318 試験に出る XI
してこのボックスフル ( LINE 〜 BF ) の結果が4096色の色見本を作るのか分からない人が
いるかもしれない。ま,それはそれでいいのである。「どしてかな一?」と考え続けていれ
ば,そのうち分かるときがくれば分かるであろう。もしも分からなかったとしても,それ
はそれで別に悩むこともない。
リスト 14-1 4096色見本 + Z 用パレ ッ トルーチン
100 CLEAR &HEF00
110 MEM$(&HEF00,16)=HEXCHR$( M DD E5 FE 03 3E 0D C0 78 PE 04 3E 05 D8 El01 C5
120 MEM$(&HEF10 f 16)=HEXCHR$( ff IF C5 3E 80 ED 79 EB 7E 23 ED 6? 0F 0F OF 0F 4F
130 MEM$(&HEF20 f 16)=HEXCHR$( tf 7E 23 E6 F0 57 ED 67 0610 ED 79 04 7E 23 B2 ED
140 MEM$(«cHEF30 f 16)=HEXCHR$( M 79 04 7E E6 0F B2 ED 79 Cl AF ED 79 C9 01 C5IF
150 MEM$(&HEF40 f 16)=HEXCHR$( tf C5 3E 80 ED 79 CD 4D EF Cl AF ED 79 C91110 10
160 MEM$(&HEF50 f 16)=HEXCHR$( M AF 67 6F 4F AF 42 ED 79 04 ED 61 04 ED 6919 C6
170 MEM$(&HEF60 f 16)=HEXCHR$( ff 1130 F2 0C C8 AC 20 EC 67 2C 18 E9 00 00 00 00
180 DEFUSR0=&HEF00
190 f
200 INIT:KLIST 0
210 OPTION SCREEN 0:WIDTH 40 f 25 f 0 f 1
220 OUT &HlFB0 f &H 80
230 GOSUB M CLS12 ft
240 # CALL &HEF3D •XPINIT
250 FOR し =0 TO 5
260 D=4 拿 <2 A U
270 IF L<4 THEN C=1 ELSE C=2
280 S=3-(L MOD 4) : SCREEN S f S
290 FOR J=0 TO 255 STEP Dt2
300 LINE(J^D f 0)-( J^2tD-l f 191) f XOR f C f BF
310 NEXT
320 NEXT
330 FOR L=6 TO11
340 D=3t(2 A (L-6))
350 IF L<8 THEN C=2 ELSE C=4
360 S=3-<L MOD 4) : SCREEN S f S
370 FOR J=0 TO191 STEP D<2
380 LINE(0 f J^D)-(255 t J-f2tD-l) f XOR t C f BF
390 NEXT
400 NEXT
410 FOR 1=0 TO 4095
420 FOR C1=0 TO 4095
430 C2=CUI
440 1 GOSUB”XPALET”
450 A$=USR0(MKI$(C1 )4^MKI$(C2))
460 NEXT
470 NEXT
480 END
490 1
500 LABEL"CLS12"
510 SCREEN,0 : CLS4
520 SCREEN,1 : CLS4
530 SCREEN,2 : CLS4
540 SCREEN,3:CLS4
550 INIT
560 RETURN
570 1
580 LABEL ff XPALET M
590 OUT &HlFC5 f &H80
600 GR=INT((Cl AND &HFFF)/&H10)
610 B=(C1 AND &HF”16
620 B0=INT(C2 AND &HF)
630 R0=INT((C2 AND &HF0)/4H10)
640 G0=INT((C2 AND &HFO0)/&H100)
650 OUT &H10004^GR 9 B^B0
660 OUT &H110O+GR t B+R0
670 OUT &H1200+GR,B+G0
680 OUT &HlFC5 f &H0
690 RETURN
で,色見本 だけではナニ なので,410〜470行で パレッ トを いじっている。 見れば分かる
と思うが,最初のループ (0 回目)で 「PALET △, △」=初期化,次の1回目のループで
「PALET △, △+:!」, さらに 「 PALETA , A +2」 ……を やっている わけ だ。 これは
無限ループになっているので止めるには BREAK キーである。450行の USR 0 を取り去
第14章 turboZ 319
;Type mismatch
PUSH
CP
LD
RET
LD
A f B
CF
4
LD
A f 5
••Illegal f call
RET
C
POP
HL
;DROP
LD
BC t 1FC5H
PUSH
BC
LD
A f 80H
OUT
(C) t A
;WRITE MODE
EX
LD
DK.HL
A, (HL)
INC
.G,A=H.B
HL
RRD
RRCA
RRCA
RRCA
; A=R.G f (HL)=B.?
RRCA
;A = G.R
LD
LD
C.A
A,(HU
; C=G.G!!
INC
HL
AND
0F0H
LD
D.A
; D=B.0!!
(HL)=r.b
RRD
;A = B.b,(HL)=0.r
LD
B f HIGH(BLUE) ; =10H
OUT
(C) f A
INC
B
; B=11H
LD
A f (HL)
INC
HL
OR
D
;A = B. r
OUT
(C) f A
INC
B
LD
A f (HL)
;A = ?.g
AND
0FH
OR
D
;A = B.g
OUT
(C) f A
POP
BC
XOR
• Z80
•PHASE 0EF0OH
EQU 1000H
EQU 1100H
EQU 1200H
BLUE
RED
CRN
參
XPALET
(HL)=?
A=B.0 f
1000
1 100
1200
EF00
EF02
EF04
EF06
BF07
EF08
EF0A
EF0C
EF0D
EF0E
EF11
EF12
EF14
EF16
EF17
EF18
EF19
EF1B
KF1C
EF1D
EF1E
KF1F
EF20
EF21
EF22
EF24
EF25
EF27
EF29
EF2B
EF2C
EF2D
EF2E
EF2F
EF31
EF32
EF33
EF35
EF36
EF38
EF39
って440行の GOSUB 文を生かすと,パレット変更ルーチンが580行からの BASIC 部分
になって,とても遅くなるので一度(一度で充分)試していただきたい。 USR 0 で実行して
いる機械語サブルーチンのアセンブルリストは リスト 14-2 である。で,それをよく見ると
なんか変なのが後ろにくっついているわけだ。そう,これはパレット初期化ルーチンなわ
けだ。リスト 14-1 の240行にこっそりとあるように , 「CALL & HEF 3 D 」 で4096色のパ
レッ トを初期化する。 EF 3 D H 〜 EF 6 B H は簡単にリロケータブルになるので(自分でやって
いただきたい), 結構 便利だろうと思う。ちなみにこのルーチンのメイン部分である EF 4 D „
〜 EF 6 B „ (計31バイト)はその筋に コン パクト設計となっている。かなり苦労して作った
からこれよりも小さく作ることはかなり難しいであろう。それよりも,きっと解読するだ
けでも一苦労だと思う。ちなみにコメントがほとんど付いてないが,これは わざとそう
したのである。 けけけけけ。
リスト 14-2 Z 用パレット投定ルーチンとパレット初期化ルーチン
3
H
X f Z
I 3 A N
5 3 D
E 0 0
4 5
0 0
5
c
F 0 9
1 8 7
7
6
o
F
7 0 9
617
9 F 9
7 0 7
D E E o 8 E E 8 115 E D B E 3
DF3C 7 F 3 D E 0 c 3 E E 7 2
DFFFFFE367
E 0000472 E5
D6D4E32D4E62D1F
B B c A
E0E072BE07E
320 試験に出る XI
OUT
RET
(C) f A ;ACCESS OFF
XPINIT :
XPMAIN
LI :
L2:
LD
BC f 1FC5H
PUSH
BC
LD
A f 80H
OUT
(C) ,A
CALL
XPMAIN
POP
XOR
BC
OUT
(C) , A
RET
LD
DE f 101OH
XOR
A
LD
H,A
LD
L f A
LD
C,A
XOR
A
LD
B f D
OUT
(C) f A
INC
B
OUT
(C) f H
INC
B
OUT
(C) f L
; D=10H
EF5E
EF5F
EF61
EF63
EF64
EF65
EF66
EF68
EF69
EF6A
19
C611
30 F2
0C
C8
AC
20 EC
67
2C
18 E9
EF3A ED 79
EF3C C9
EF3D 011FC5
EF40 C5
EF4 1 3E 80
EF43 ED 79
EF45 CD EF4D
EF48 Cl
EF49 AF
EF4A ED 79
EF4C C9
では説明に入る0そこでリスト 14-1 の 580 〜 690 行なわけだ。これがパレット設定の基
礎である。
ここでは 「PALET Cl , C 2」 に相当することをしているわけである。まず大事なことは
I / O の 1 FC 5„ のビット7,ビット3である。これは第0章を見れば分かるであろうが , tur
boZ モードでアナログ RGB のパレット設定に先立っては,「ビット7=1,ビット3 =
0」としておかなければならないのである。ビット7 =1はアクセス ON , ビット3 = 0は
書き込みモード (1 なら読み出しモード)ということである。そして,できれば680行に
もあるように,設定が済んだ後は「ビット7 = 0」としてアクセスを OFF にしておくべき
である0さもないと, LIST , INIT 命令などの「パレットをいじるが,アナログ RGB には
対応していない命令」が,おかしなパレット設定をしてしまうことがある。
その後は,3回の OUT 命令を実行するのだが,その方法がちょっと違和感のある形式に
なっている。が,一つ例をあげればたちまち分かってしまうだろう。すなわち,
PALET &H 〇△口,
は,
OUT &H10OA, &HD y
OUT &H110A, &UD/3
OUT &H12 0A, &HD^
E H 2
D 1 L
HlA f
c z
t A
z » 2
H N H L L
DDDDRNCETrNCo:ND
A A J I R XJLIJ E
0
1
0
1
9 19
7 6 6
1F7FFF2D4D4D
1A664A4E0E0E
D 012345689 Be
455555555555
FFFFFFFFFFFF
HHEEEEEEEEP^E
第 14 承 turboZ 321
になるのだ。ただし〇△口, a /? y というのは,それぞれ「1桁の16進数」である。具体的
な数字をあげると,
PALET & HABC,&HDEF
は,
OUT & H 10 AB,&HCF
OUT & H 11 AB,&HCE
OUT & H 12 AB , &HCD
となるのだ。 rc 」 が 「 out される数値」の方に回されているというのが微妙なのであ
る。ま,これだけ言っておけば大丈夫であろう。あとはリスト 14-2 であるが,これは
「 RRD 」 の使い方がなかなかである。この命令は 「 A レジスタの下位4ビット」, 「( HL ) の
上位4ビット」, 「( HL ) の下位4ビット」の三っの間で値を回すという命令である。詳し
くは参考文献4を見ていただきたい。で,気を付けなければいけないのが,この命令を実
行すると ( HL ) が書き換わるということである0よって,たとえばリスト 14-1 の450行
を,
X $ = MKI $ ( CD+MKIS ( C 2) : A $ = USR 0 ( X $)
などとすると, X $ の中身が害き換わってしまうのである。というわけで,この点は注意す
〇よ一に。
次に リスト 14-3 である(100〜200行と480行以降はリスト 14-1 と同じである)。これは
64色 x 2画面モードである。280〜370行で64色モード用のパレットを設定し,390〜470
行で二つのグラフィック画面+キャラクタのプライオリティ(優先順位)をパコパコと切
り換えている(ついでにテキストパレットもランダムに変えている)〇何かキーを押すと終
了する。そいでもって,このときのパレットの設定であるが, 「 R , G , B それぞれの下位
2ビットが無効」ということになっている。すなわち,
青— 00010000 **xx "xx : **xx 木"*
赤— 00010001 **xx * * x x : * * x x ****
緑一 00010010 **xx * * x x : **xx ****
10 m ,11 hJ 2 m G R B G ', R ', B #
において, r *」 が有効なビットで, 「 x 」 が無効なビットということである。「 X 」の部分
は注意深く避けないと,予期せぬパレットが設定されたりする。なぜかというと,たとえ
ば 「 OUT & H 10 FF ,& HF ?」 と 「 OUT & H 10 CC ,& HC ?」は同じだからなのだ(無効
ビットを0として考えれば分かる)。よって,前者と後者の両方を実行して,なおかつ「?」
の部分が双方で違っていたなら,「あれ? パレットがヘンだぞ J ということになるのであ
る。ま,ここらへんは結構複雑で面倒臭いから,しばらくあれこれといじってみるのが一
番手っ取り早いであろう。
リスト 14-3 64色 X 2 サンプル
322 試験に出る XI
1 > 拿 &H800M (I V 2) AND
1 (I ¥ 2) AND
C2))
1 > 拿 &H80 +(1 AND 1 > 拿
1> 拿 +(1 AND 1> 拿 &HF
)AND
)AND
I$(C
FOR 1=0 TO 7
Cl = ( (I ¥ 4
C2=((I V 4
A$=USR0(M
NEXT
CLEAR &HEF00
MEM$UHEF00,16>=HEXCHR 拿 (”DD E5
MEMSUHEF 10,16 >=HEXCHR$< M 1F C5
MEM$ (&HEF20 f 16 ) =HEXCHR$ ( tf 7E 23
MBM$(&HEF30 f 16)=HEXCHR$( M 79 04
MEM$(&HEF40 f 16)=HEXCHR$( tf C5 3E
MEM$(&HEF50 f 16)=HEXCHR$( ff AF 67
MEM$ ( &HEF60 f 16 ) =HEXCHR$ ( ff 1130
DEFUSR0=&HEF00
130 MEM$(&HEF20 f 16)=HEXCHR$( ff 7E 23 E6 F0 57 ED 67 0610 ED 79 04 7E 23 B2 ED"}
140 MEM$ (&HEF30 f 16) =HEXCHR$ ( ff 79 04 7E E6 0F B2 ED 79 Cl AF ED 79 C9 01 C5IF 11 )
150 MEM$ (&HEF40 f 16) =HEXCHRS ( ff C5 3E 80 ED 79 CD 4D EF Cl AF ED 79 C91110 10 lf )
160 MEM$ (&HEF50 f 16) =HEXCHR$ ( f# AF 67 6F 4F AF 42 ED 79 04 ED 61 04 ED 6919 C6">
170 MEM$ (&HEF60 f 16) =HEXCHR$ ( ,f 1130 F2 0C C8 AC 20 EC 67 2C 18 E9 00 00 00 00 tf )
180 DEFUSR0=&HEFO0
190 1
200 INIT:KLIST 0
210 OPTION SCREEN 0:WIDTH 40,25,0,1
220 OUT &HlFB0 f &H80
230 GOSUB”CLS12"
240 CALL &HEF3D f XPINIT
250 SCREEN, 0: SYMBOL (0 f 0) f M 0 ,f f 8 f 4 f 1 f 0
260 SCREEN, 2: SYMBOL (30,30) f ff 2° f 8 f 4 f 2 f 0
270 •
280 OUT &HlFB0 f &H 90
290 FOR G=0 TO15 STEP 4
300 FOR R=0 TO15 STEP 4
310 FOR B=0 TO15 STEP 4
320 Cl=Gt&H100+R»4H10^B
330 C2=C1
340 A$=USR0(MKI$(C1 )-fMKI$(C2))
350 NEXT
360 NEXT
370 NEXT
380 1
390 SCREEN 0,0: LOCATE 0,5: PRINT STRINGS {12 f >
400 FOR J=0 TO 8 STEP 8
410 FOR 1=0 TO 2
420 D=16^J^I : LOCATE 20 f 15:PRINT HEX$(D)
430 OUT &HlFC0 f D:PAUSE 15
440 NEXT
450 NEXT
460 IF INKEY$ = ftft THEN 400
470 END
480 1
490 LABEL ff CLS12 ff
500 SCREEN,0 : CLS4
510 SCREEN,1 : CLS4
520 SCREEN,2 : CLS4
530 SCREEN,3 : CLS4
540 INIT
550 RETURN
turboZ では上記のブログラムで示した以外にもさまざまな画面モードがあるわけだ。そ
れらの場合にはどんな色数が使えて,パレットの設定はどうするかという問題がある。そ
れ にいちいち 答える の も面倒なので,一番おいしそうな「640 X 400で4096色中から8色を
使用可能」をリスト 14-4 に示す。
リスト 14-4 640 X 400 で4096色中8色モード
INIT:KLIST 0
OUT &HlFB0 t &H 80
OPTION SCREEN 0:WIDTH 80,25,1,2
CLS4
t
FOR 1=0 TO
LINE(It30
NEXT
100+ I 拿 30,100+1*20) f PSET f I f BF
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
第 14 章 turboZ 3
8 F E 9 9 D 0
D 0 7 c c B 0
5 F 4 9 9 4 9
0 0 0 7 7 0 B
E 7 9 D D 1 B
3 6 7 E E 61
4 D D F F D c
0 E E A A E 2
E 3 0 11 4 7
F 2 1 c c 0 6
8 E 6 9 F 9 c
7 7 0 7 E 7 E
0 B 7 D D D 0
c E 6 E 4 E 2
D 9 D 2 D 2 c
0 7 E B c 4 A
E D 7 F 9 F 8
3 E 5 0 7 A c
3 0 0 6 D F c
0 8 F E E 4 0
E E 6 E 0 F 2
F 3 E 7 8 6 F
FOR 1=0 TO 7
C1 = ((I ¥ 4) AND 1)*«tH800-f( (I ¥ 2) AND 1)*4H80 +(1 AND 1
C2 = RND( "*4096
A$=USR0(MKI$(C1)+MKI$(C2))
NEXT
GOTO 350
で,これらの基本は,
1) 低解像度 (15 kHz ) のときは,多色モードにするとバンク0,バンク1が重ね合わ
さって 一つの 色になる
2) 高解像度 (24 kHz ) のときは,多色モードにするとバンク0,バンク1が別々にな
り,同時に両方の面を見ることができない。それに伴い, IFCOh 番地の優先順位などは
意味を持たなくなる(キャラクタとの間の優先順位はあるが)
3) 色数は, 320 x 200 の4096色モード以外は, 640 X 400 のときが8色なだけで後はす
ベて1画面64色である
4) パレ ットの指定は常に RGB の下位ビットから無効になっていく
なお補足しておくが, Z では IN 命令により,その時点でのパレット設定値の読み出しも
可能になっている。 Xl / turbo では値を読み出せなかっただけではなく,パレットの設定が
変わってしまったりしていたのである。これは特に大きなメリットがあるわけでもないが
(もちろん CZ -8 FB 03 の PSAVE などはおいしいが),とりあえずは前進であろう。具体的
な,パレット設定値の読み出し方法は,
1) 1 FC 5„ の第7ビットと第4ビットを1にする。これで多色モードかつ,パレットは読
み出しモードとなる
2) OUT & H 10 GR , B ? を実行する〇「?」は何でもよい。このとき,パレットは読み
出しモードなので,新しい値の設定はされないことに注意。この後, B ' = INP (&H
10 GR ) AND & H 0 F とする
3) 「& H 10」 を 「& H 11」 に置き換えて R ' を得る
4) 「& H 10」 を 「& H 12」 に置き換えて G ' を得る
5) こうして得たがパレットの設定値
ということになる。
ところで,テキストパレットはそれぞれに64色(階調)を指定できるのであるが,美し
くないことにカラー0 =黒は黒のまんまなのである〇 I / O アドレスから見ると 1 FB 8„ 番地
が臭いのであるが,残念ながらだめである。すなわち,この機能を使ってキャラクタの黒
色を他の色に変えることはできないよ一である。
で,極めて当然のことながら,テキストパレットは PCG にもかかわってくるのであ
る。よって, turboZ では, PCG で使える色数が大盤振舞されているのである。
画像取り込み
これはなかなか画期的な機能であるが,使い方はものすごく簡単なのでブログラムだけ
載せておく。まず リスト 14-5 は単純に画像取り込みをしつつ,位置補正をするプログラム
324 試験に 出る XI
0 0 0 0 0 0 0
4 5 6 7 8 9 0
3 3 3 3 3 3 4
である。110行の所でマイナスの値を入力すると取り込みをやめるのである。ちなみに,
CRT 3 というのはスーパーインポーズをする命令である。 turboZ で画像取り込みをするた
めには,スーパーインポーズ画面でなくてはいけないのだ。
リスト 14-5 画像 取り込み+ 位置補正
100 WIDTH 40,25,0 , 1 :OUT&H1FB0 , &H88:CRT 3
110 INPUT A
120 IF A>=0 THEN OUT &H1FC1,A:GOTO 110
130 OUT &HlFB0 f &H80:CRT 1
140 END
次に リスト 14-6 である。これはモザイク処理である。入力は8進数で行なうことと,
X , Y 方向のモザイク指定には無効な部分があることに注意。ちなみに「56」を入力して
大きなモザイクにした後で | SHIFT 1+[71 でコンピュータ画面にすると,それはそれな
りに楽しい画面となる。入力のときに8進数ではなく「 .. J を入力するとクロマキーのデ
モとなる。これはさりとて面白いわけではない。無限ループだから適当な所で BREAK す
ること。
リスト 14-6 モザイク+クロマキーサンプル
100
WIDTH40, 25,0,1 : OUT&H 1 FB0 t &H88 : CRT
3
110
OUT &H1FC2,0
120
OUT &H1FC3,0
130
OUT &H1FC1,40
140
INPUT AS:IF A$= M .. M THEN
180
150
A = VAL("&0" + A$ >
160
OUT &H1FC2,A : GOTO140
170
1
180
OUT &HlFC2 f 0
190
OUT&H1FB0,&H80:CRT 3
200
FOR X = «cH80 TO «cHC0 STEP .
ScH40
210
FOR 1=0 TO 7
220
C=(I AND 4>*8+(I AND
2)*4 + (I
AND 1> 拿 2
230
PRINTBIN$(X OR C)
240
BEEP:OUT &H1FC3.X OR
C : PAUSE
10
250
NEXT
260
NEXT
270
GOTO 200
そして最後が リスト 14-7 のスクロールである。 turboZ にはスクロール IN / OUT とい
う機能が付いているが,それのサンプルである0お勧めの入力は8,9,10,11,12など
である。そのうち「12」は, CRT 出力をカットすることになる。これは別にスクロールと
組み合わせる必要はなく,画像取り込み中であろうが,スーパーインポーズ中であろう
が,普通のコンピュータ画面であろうが,とにかく CRT 出力をカットしてしまう。ビデオ
マニアにはおいしいであろう。ところでなかなか面白いのがスクロールとモザイク処理付
きの画像取り込みの組み合わせである。モザイク処理部分がクルクルと回ってなかなかに
面白い。
以上であるが,細かい点であちこちに取りこぼしもあるだろう。 一つには turboZ の拡張
機能は,カスタム LSI を使ったものであるために,面白そうなもの,便利そうなものを何
第 14章 turboZ 325
リスト 14-7 スクロール サンブル
100 WIDTH40, 25,0,1 :CRT 3
110 SCROLL 2
120 INPUT N:IF N<0 THEN 160
130 OUT &H1FC4,N
140 GOTO120
150 1
160 SCROLL 0
170 OUT &H1FC4,0
でもかんでも寄せ集めたという感じだからでもある。たとえば画像取り込みに,「反転階
調」などというものも指定できるのであるが,どう考えてもこれの用途は,反転をボカシ
の代わりにしたその筋のビデオを,もう一度その筋する機能ぐらいの意味しかないように
思うのだが,どうであろうか(今度やってみよ)〇それ以外にもやり残したのに「インタレ
ーススーパーインポーズ」 もあるが,これはビデオ編集専用であろう。その方面の趣味を
持っている方はスクロール IN / OUT の機能とともに大変おいしいであろう。てなところ
で turboZ であった。
326 試験に出る XI
付 錄
A ダンプリストチェック用プログラム
巳 XI 処理技術者試験
C 初出一覧•參考文献
付録 A 1 ダンプリストチェック用プログラム
リスト A -1 はダンプリストチェック用のプログラムである。ごちゃごちゃしているので,
打ち込みには充分に注意すること。リスト A -2 が機械語部分のアセンブルリスト,リスト
A -3 がその部分を自分自身で表示させたものである。
リスト A -1 ダンブリスト チェックツール
00
10
20
30
40
50
60
70
80
90
:00
:10
20
!30
:40
:50
260
:70
:80
90
;00
10
• 20
30
40
50
60
70
T=&HC00O:CLEAR T
MEM$(T+ 0 f 16)=HEXCHHS( M 05 C8 EB E5 56 23 5E 23 05 281C EB 0E 80 1A A1
MEM$(T+16 f 16)=HEXCHR$( M 28 0137 ED 6A 30 08 3E 10 AC 67 3E 21 AD 6F CB
MEM$(T^32 f 12)=HEXCHRS( tf 09 30 EB 1310 E8 EB El73 23 72 C9 M )
DEFUSR0=T
DEFINT B-Z:DIM X(7)
INPUT A$
B = VAL( lt &H M fMID$(A$ l 2 f 4) ) :IF B>=0 THEN 160
C = VAL( , # «cH tf +MID$(A$ f 7 f 4) ) : IF 0 = 0 THEN 160
FOR D=B TO C STEP 128
IF D.127<C THEN E=127 ELSE E:C-D
Z$ = LEFT$(MEM$(D f 1)4STRINGS(127 t 0) 9 128)
F=0:FOR J=0 TO 7 : X(J)=0:NEXT
FOR 1=0 TO15
IF D+F く :: C THEN E$ = HEX$ ( D^F ) ♦ fi ••: GOSUB 360 ELSE I =99:GOTO 290
Y=0:FOR J=0 TO 7
G=ASC(MID$(Z$ f F^l f 1)) : Y=Y^G : X(J)=X(J)^G
IF F<=E THEN E$ = RIGHT$ < "0" + HEX$ <G> , 2 > ♦•• •• ELSE I =99 : E$ = SPACE$ ( 3 )
GOSUB 360:F=F+1 :NEXT:E$: ••: ff ♦RIGHTS ( tf 0 ff ^HEX$ (Y ) f 2) : GOSUB 340
NEXT : E$ = STRING$ ( 33 f ff - ff ) : GOSUB 340 : E$:"SUM : •• : GOSUB 360
FOR J = 0 TO 7:E$ = RIGHT$("0" + HEX$(X( > t 2> ♦” ••: GOSUB 360:NEXT
ZS = USR0(LEFTS( Z$ f E+1)):IF E = 0 THEN Z$ = Z$ + Z$
E$ = RIGHT$r000^HEX$(CVI(LEFT$(Z$ f 2) ) ) f 4) : G0SUB 340 : E$ = ffM :GOSUB 340
NEXT:END
GOSUB 360 : IF LEFTS (A$ f 1) = if P tf THEN LPRINT ELSE PRINT
RETURN
IF LEFT$(AS f 1) = #f P M THEN LPRINT E $; ELSE PRINT E$ ;
RETURN
CRC 計穿•ブ
• Z80
C000
0001
C002
C003
C004
C005
C006
C007
麟
C008
C009
C00B
C00C
C00B
C00F
C010
C012
C013
C015
05
C8
EB
B5
56
23
5B
23
05
281C
EB
0B 80
1A
A1
28 01
37
ED 6A
30 08
LOOP
SKIP
•PHASE
0C000H
; 0R ANY PLACE
ADDR
H
DEC
B
RET
Z
; LBN=1 THEN RBT
EX
DB»HL
PUSH
HI/
;SAVB VAL ADDR.
LD
D,(HL)
INC
HL
LD
B,(HL)
INC
HL
DEC
B
JR
Z.FINIS
: JUST 2
EX
LD
DE»HL
; HL=SBBD f DB=ADDR.
C 9 80H
••MASK
LD
A f (DB)
;DATA
AND
C
;CHECK
JR
Z.SKIP
SCF
; CY=1
ADC
HL V HL
••HL=HL+HL+CY
JR
NC f NBXT
;NBXT BIT
328 試験に出る XI
C000 05 C8
C008 05 28
C010 28 01
C01810 AC
C020 09 30
0028 73 23
SUM : BE F0 02 D7 FF 68 DA AE C076
使い方を説明する。まずはリスト A -1 を問違いないように打ち込む。特に110行〜130
行は注意して打ち込むこと。打ち込み終わったら RUN する前にセーブしてお 〈。そして,
そのディスク(もしくはテープ)を取り出しておく。その後に RUN して動作チェック
を行なう。 RUN した後, 「 DC 000 C 02 B ^ j でリスト A _3 のように表示したらひとまずは
OK である(あくまで ひとまず である。まだまだバグが入っている可能性がある)。打ち込
み問違いがないということはまずあリ得ないから,一発で動くとは期待しないように。バ
グを取っている間,技•走させてディスクを壊したりしないように,くれぐれも注意してい
ただきたい。
で,プリンタに打ち出す場合は 「 PC 000 C 02 Bj のように 「 p 開始アドレス終了アドレ
ス j である。 アドレスは常に4桁の16進数で指定すること。 またこのブログラムでは0000
〜 7 FFF のアドレスは指定できないようになっている(必要もない)。
チェックするポイントは,リスト A -3 で になっている部分である。特に右下
隅の4桁の16進数は大事である。
また,このプログラムで第10章の MML プログラムをチヱックするときは,前もって
NEW ON & HD 000 を実行しておいてからリスト A -1 と MML プログラムをロードし,100
行の 「CLEAR T 」 を削除してから RUN していただきたい。
余談で あるが,100 行の T = & HC 000 は,別に C 000 でなくてもよく, D 000, E 000,
F 000 などでもかまわない。よ一するに チェックする機械語プログラムと重ならないアド
レスならどこでもよいので ある。
C017
3E 10
LD
A f 10H
C019
AC
XOR
H
C01A
67
LD
H f A
C01B
3E 21
LD
A, 21H
C01D
AD
XOR
L
C01B
6F
•
LD
L.A
; HL=HL XOR
C01F
CB 09
NEXT :
RRC
C
;ROTATE MA
C021
30 EB
JR
NC f LOOP
;RIGHT BIT
C023
13
INC
DB
•NEXT BYTE
C024
10 E8
•
DJNZ
LOOP
••DEC COUNT
C026
EB
t
EX
DE V HL
C027
El
FINIS :
POP
HL
;QBT ADDR.
C028
73
LD
(HL) f B
C029
23
INC
HL
C02A
72
•
LD
(HL) f D
••SAVE
C02B
C9
•
•
RET
t
END
スト A -3 出カサ
7 D D 9 B 1
9 7 2 6 F D
31 E B 1
2A3 c E
E A 8 F B
51 0 6 E
3 0 0 D 8
2 8 3 A E
6 E A 1 0
5 0 6 2 1
5 B D E 3 9
E E E 3 1 c
B c 7 7 B 2
E 13 6 E 7
付 録329
付録 B XI 処理技術者試験
最近は钦弱なバソコンユーザーが增えている0
そんなことではいけないので,ここにとリあえず XI 処理试験を用意することにした。
おのおのの段階に応じて,第2種その筋,第 1 M その筋,特種その筋が認定される。た
だし面倒吳いので,勝手に採点して勝手に認定されていただきたい。
なお,試験問題にはロクでもないものも含まれているので,心してかかるように。
注意事項
試験時問は無制限の金網デスマッチ3本勝負である。リターンマッチも町であるから,
大いに頑張っていただきたい。ただし,ずるはしないように。
1 . 適性試験
問以下の項目に YES / NO で答えよ
(1) 必要ないと分かっていても,ついつい敁適化してしまう
(2) どんなプログラムでも「もう1バイト短くできる j と信じている
(3) どんなプログラムでも「もう1クロック速くできる」と信じている
(4) 指を10ビットのメモリとして使ったことがある
(5) プログラミングしながら H の出を迎えることは,それほど珍しくない
(6) CRT は目に悪いと体感している
(7) 戦 M 機のフライトシミュレ ー タは曲•白そうなゲームである
(8) 10進法は不自然である
(9) 頭の中に丧レジスタがある
(10) 「 CDj とは音楽用語ではなく CALL のことである
(11) 「地丧雷火事停屯 j である
(12) 頭の中にフラグレジスタがある
(13) ディスヶットの磁性面に触るようなやつは死刑にすべきだ
(14) パソコンの前で食事することが多い
(15) プリンタ用紙にメモすることが多い
(16) BASIC よりも機械語の方が便利だ
(17) 老後の趣味はプログラミングと決めている
以上17項目のうち9項目以上に YES と答えた方はその筋陽性ですので,第2種その
筋を名乗ることを許可します。
2 .第〗種その筋試験
問1 PSG のレジスタ設定について答えよ
a ) 花子さんはおかあさんから XI の PSG を使って 300 Hz の音を出して欲しいとた
のまれました。チャンネル A を使うとしたら, R 0 , Ri にはどんな数を設定すれば, 一
330 試験に出る XI
番 300 Hz に近い周波数の音が出るでしょうか。
b ) 太郎君はその筋なので, XI を使って出せる一番低い音(周波数の小さい音)を
出してみようとしました。さて,太郎君が出した音の周波数はいくつでしょう。小数
点第2位で四捨五入して答えなさい。
問 2 パレ ツトの設定に ついて 答えよ
NEW BASIC と turbo BASIC の コマン ド 「 PALET@j は 一つの コマン ドで最大八つ
のパレットを設定できる コマン ドである(知らなかったら ><)〇
そこで 「 PALET @ 文に相当する3バイトのデータ」について答えよ。
a ) 資料を見ずに,初期状態の「3バイト」を答えよ。また,その3バイトはそれぞ
れ何番地に OUT するか?
b ) 「 PALET @ 4,1,2, 6, 4,1,2, 6 j に対応する 3 バイトは?
c ) グラフィックを4色だけに制限する代わりに,青〉赤 >鉍 ( + ! S ) の後先順位で
使えるようにしたい(勝手な話•だが,この時点で何を言おうとしているのか分からな
かったら >0。 青を PLANE 0(4000 h 〜7 FFF h ), 赤を PLANE 1 (8000 h 〜 BFFF h ), 綠
を PLANE 2 ( C 000 H 〜 FFFF H > とするには,どうすればよいか。 「 PALET @ ?,?,
?, ?,?,?,?, ?」 と 「3 バイトの データ j で答えよ。
d ) c ) と似たケースで, f 4( PLANE 0>> 宵 ( PLANE 1)〉 赤 ( PLANE 2) ( + Wt ) の場
合に ついて 答えよ。
e ) 4 色ではなく 5色に制限して青,赤,鉍> 白 (+ 黒)としたい 0 パレット コード
を 青 = 1 , 赤=2,緑=3>白 =4 (黑 =0) とするにはどうするか。 「 PALET @
?,?,?,?,?,?,?, ?」 と「3バイトの データ j で答えよ。
問3 次の式を ウンウン 言いながら暗算して16進数で答えよ0ただし〜 B は2進数, 〜〇は
8進数を表すものである 0
a ) FAh +27 h +34 h
b) FF h x 1011b
c ) 774〇 + 444〇
d) 10 h x 11h + 2 Ah
e ) 0 F h xoF h
f ) 716 h +2
g) /100 h
h) ^144 h
i ) /2710 h
問 4 次のサブルーチンの実行時間を計算し,クロック数(ステート数)と時間〇 / S の単位)
を答えよ。もちろんクロックは 4 MHz とする。ただし Z 80 の解説害を参照してもよろ
しい。
付 録
a )
LD
A ,10 0
LOOP : DEC A
RET Z
JR LOOP
b )
LD A ,10 0
LOOP:DEC A
J P NZ , LOOP
RET
c )
LD A ,10 0
LOOP : DEC A
JR NZ , LOOP
RET
d )
PUSH A F
PUSH DE
LD DE ,151
LOO P : D E C DE
LD A , D
OR E
JR NZ , LOOP
JR SKIP
S K I P : O R A
POP DE
POP A F
RET
問 5 HL レジスタ x ms だけ(よ一す るに HL = 1なら1 ms , HL = 2 なら 2 ms > 時間つ ぶ
しをするサブルーチンを作りたい ( HL = 0のときは考えなくてよい)。ただし, p 乎び
出す側での,
PUSH HL
LD H L , nm ; Mm 杪か
CALL そのサブルーチン
332 拭験に出る XI
呼び出し例
PUSH
LD
HL
HL,1234
WAIT :
LOOP :
FINIS
CASE0
WS :
CALL
WAIT
POP
HL
サブルーチン
PUSH
AF
PUSH
DE
NEG
DEC
HL
LD
A,
H
OR
L
JR
[[l)l f CASE0
LD
DE,_
CALL
WS
BIT
0,(HL)
DEC
DE
OR
A
LD
DE,_
NEG
NEG
CALL
WS
DEC
(4)
LD
OR
T ?)
JR
NZ
,LOOP
: POP
POP
DE
AF
RET
: LD
DE
• _
CALL
WS
JR
FINIS
DEC
DE
LD
A,
D
OR
L
JR
NZ
f WS
RET
b ) 上記のプログラムを短く作り変えなさい(これは簡単)
3. 特種その筋試験(論文)
a ) 第14章のリスト 14-2 ( turboZ の4096色パレットの初期化〉の EF 4 D H 〜 EF 6 B „
の部分の I 力作を理解し解説せよ。
b ) それと同機能で,より短いサブルーチンを作れ。もしも不可能と考える場合は,
不可能であることを証明せよ。
POP H L
の時間も入れて考えるとする。
a ) 空いてる所をその筋な文字列で埋めなさい(甘えは許しません)
10 7 0
1111
4
7
/
2 0 7 2
11116 4
0
1
81
4 4
7
/
2 0 0 0 0 7 2
1 1111 11 1A 1
7
/
2 0
1 n
付 録 333
【解答】
第1種 その 筋試験
問1
a ) R 0 = 161, Ri = l
b ) 30.5 Hz
問 2
a ) AA h , CCh , FOh の 3 バイト
OUT する番地は,
AA h —1000 H 番地
CC H —1100 H 番地
F 0 h 4120 0 H 番地
b ) 22 h , CC h , 99 h
c ) PALET @ 0, 1, 2,1, 4,1, 2, 1
AAnt 44 »t 10 h
d ) PALET @ 0, 7,1, 7, 2, 7,1, 7
EEh * BAh , AAh
e ) PALET ® 0,1, 2, 4, 7,1, 2, 4
32 … 54„, 98„
問 3
a ) 155 h b ) AF 5 h c ) 320 h d )13 A H e ) El H f ) 38 B H g )10 H
h )12» i ) 64 h
問 4
a ) 2695 ク ロック,673.75 jus
b ) 1417 クロック,354.25 jus
c) 1612 ク ロック, 403//S
d ) 3999 クロック,999.75(けけけけけ)
問5
a )
(1 )Z (2) 147 (3) 151 (4) HL (5) A , H (6) L (7)147
b )
自己採点しなさい。②と⑦がともに「147」であることを使えば簡単。もちろんそれ以
外でもよい。
特種 その 筋試験
解答が載っているなどと思っていた人は失格。
334 拭験に出る XI
付録 C 初出一覧•参考文献
【初出 一覧】
各飫の Oh ! MZ 誌违敉時における褐号とタイトルを下記に示す。
第〇飫きつと完全無欠な I / O マッブ——’85年6月号「第1回たぶん完全無欠な I / O マッ
プ」,’87年2月号「第21回はとんど完全無欠な I / O マップ j
第1积 CRTC でどすこいである——’85年 7)1 号「第2回そこに CRTC があるからなのだ j
第2現 PCG は二度おいしいのである——’86年3月号「第10回 PCG のお通りである j
第3饫潢字名! ff 出亜留——’86年11月号「第 18 L « J と一と 一 漢字なのである j
第4京サブ CUP のおかげなのである——’85年10月号「第5回サブ CUP は必修科目なの
である j
第5章. CTC は作儀なのである——’86年 Oj 号「第11回 CTC はきちょ 一 めんなのである j
第6章 SI 0 でマウスである——’86年5 I 】号「第12回 SI 0 は通信ばかりではないのである j
第7砍通信だつてするのである——’87年8 fj 号「似終1»1通信プログラムである j
第8祆 DMA はへビー級である——’85年 • 8 H 号「第 3 ㈣ z 80の一族はただ者ではないので
ある」,’85年9 J 1 号「第4 W DMA はグラフィックもしてしまうのである j
第9饫ディスクを [ n ] すのである——’85年 12 fj 号「第7回钦式円盤の基礎である」,’86年1
IJ 号「第 8 fclFDC は挑戦的である」,’86年2 II 号「第9回 FDC は業師なので
ある」,’86年7 fj 号「第14间 DMA にはディスクがよく似合うのである」
第10隶 PSG は基本である——’85年11月号「第6回 PSG はてりめぇである j
第11饫 FM 音源ナハトムジーク——’87年 5〗 j 号「第 23 M FM 没凋するのである j , ’87年6〗]号
「第 24 N MML を作るのである j , ’87年7 fl 号「第25回 MML を完成するので
ある」
第12饫カラーイメージボードで取り込むのである——’87年4月号「第22间カラーイメージ
ボードなのである j
第13坎テープもやってしまうのである——’86年6 H 号「第13回あげくのはてにはテープな
のである j
【参考文献】
1. 「XI マシン語 活用百科」,清水保弘矜,産笼報知 センター 刊
2. XI turbo 回路図公開, 「0 h ! MZj , ’84 年 4 月 号
3. 絞インターフヱイス LSI の研究 CRTC [ HD 4650 5] 編,「マイコンピュータ No . 8ム千
葉:#界, CQ 出版社刊
4. 「 Z 80 ファミリ.ハンドブック」, 額田忠之矜, CQ 出版社刊
5. 「プログラマブルサウンドジェネレータデータマニュアル j , ゼネラルインスツルメン
トインターナショナルコーポレーション ( GI > 刊
6 .「 YM 2151 ューザーズマニュアル 」, U 本楽器製造株式会社刊
7. 「 CZ -8 BS 1 取扱説明寄 j , シャープ 刊
8. 「 XI システム研究室」,有 田降也,牛鸣昌和, I . Rittaporn 苦, tl 本ソフトバンク 刊
9 . I/O ’85 年 7 号「マイクロプロセッサを 比較す る回 」, Processors Professor 苦, I :
学社刊
10. 「敁新フロッピ•ディスク装菜とその応用ノウハウ j , 高橋#司苦, CQ 出版社刊
11. 「ガラスの仮面 j 1〜34巻,美内すずえ其,白泉社刊
12. 「小さなお茶会 jl 〜6巻,描十字社著,白泉社刊
付 録 335
A
ALG .281
AM .208
AY -3-8910 .230
互
BASIC ROM .13
BCD .90
Bin .184
BIOS ROM .20
bps (ボー) . 99
BUSY . 192,212
CZ -8 RL 1. 79,310
CZ -8 RS .12
可
DATA .210
DATA REQUEST .189
Device dump .181
DI .84
DISPTMG 信号 .36
DMA .21,148,217
DOS .193
"e"
c
CG .
CHDIR .
•麄•麄■■鏖耋#癱龜巍■龜巍■癱■巍 ■
. 16,56
. 186
... . . 1 〇〇
し . 上〇厶
ハ C . 70
lvivyo .
CP/\A .
. /〇
し r / ivi .
CRC .
CRTC(CRT コントロ
PR 1 1^ .
. 210
ー ラ) ……16,32,46
し !^ 」 「
.
し 1 し
rTTmcp 僧杜 . .
. Cly VOy ZOy
. . oc
| ロワ . ou
ハ 1 r 1 , n パ八ヂ ■■麄_ •巍巍癱麄龕■巍■巍■撬巍癱雌雜■■巍■■■■■■■■翁__ _ 1〇 A
V .
CZ-8BM2 .
CZ-8BS1 .
CZ-8BV1 .
CZ-8BV2 .
CZ-8CB01 .
. lOVJ
. 98,132
. 242
. 284
. 284
. 44
EMM . 13,163
El .83
F
FA 丁 . 182,184
FD . 14,217
FD 1791 ファミリ .187
FDC .187
FDD . 192
FM .179
FM 音源 . 11,242
FM 記録方式 .179
GAP .208
G (グラフ イ ック ) -RAM . 28,163 ,226
TT
CZ -8 FB 01.44,196 HD 46505 -SP .33
CZ -8 FB 02 . 219,318 HLD .192
CZ -8 FB 03 .318 HLT .192
索引
IBM フォーマット . 176
ID. 204,209
INDEX ホール . 205
INP 関数 . 226
INT . 86
I/O.10
IPL . 182,184
IPL ROM.20
1ST .245
I レジスタ .86
了
JIS 漢字コード .64
K
KILL .185
LFO.247
LF コード .133
M (メガ) .
.
.231
.10^7
iviuoo/ u . lOI
TV if 000^77 . 1 O ワ
iVlUOO/ / .
MFM .
.
10/
.179
ivirivi pC 踩 n y\
MKDIR .
MML .
//PD765 ファミリ ••…
.186
. 242, 260, 276
.187
N
NMI .
NOT READY .
~o
OPM.
OPN.
p
PCG.
PIO-3055-01.
PSG .
RAM CG .
RESTORE .
ROM CG .
RS-232C.
T
SCSI .
sector .
side .
SIO .
Sync.
Sys .
T
TL.
track .
turboZ .
TV.
TYPE (FDC コマンド)
•86
192
242
242
16,25,41,44
.13
……20,230
.44
.219
.44
12, 98, 132
.14
.181
.180
21,98,114
.208
.184
251
180
11,318
…… 89
338 試験に出る XI
188
y _
VIP .245
VRAM . 46,162
w
WNBSY .191
Y
YM 2203 .242
インフオメー シヨンブロック
つ
ウィンドウ .
丈
エッジ .
エン K つ一 K .
エンド . オブ • ブロック … •
エンベロープ .
303
128,289
……314
……133
157, 226
230, 245
Z 画像取り込み位置補正指定 . 23
Z クロマキー指定 . 24
Z スクロール 指定 . 24
Z テキストパレット指定 . 22,324
Z 80 . 99,114,148
Z プライオリティ指定 . 22
Z モード指定 . 22
Z モザイク取り込み指定 . 23,325
ZM 子化取り込み指定 . 23
th
アタックレート . 246,251
アトリビュート . 182
アルゴリズム . 245
インクリメント . 220
インター•リーブファクタ . 207
インタラプトレジスタ . 86
インタ レーススーパー イ ンポーズ ……318
インタレースモード . 35
インデックス ホー ル . 178,205
音階 . 277
音 M . 230
階層化ディレクトリ . 182,186
解像度 . 324
外部クロック . 99
外部 RAM ボード . 13
外部 ROM . 13
カウンタ . 99
カウンタモード . 101
カセットデッキ . 90
カナの表現方法指定 . 133
画面管理 . 25
カラーイメー ジ ボード . 11,284
カレンダー . 90
漢字コード . 64
漢字 ROM . 13,16,71
漢字 VRAM . 28,68
T
キーデータ . 88
索 引
キー人力 . 84
T
区点つ 一 K . 64
クラスタ ( cluster ). 182
グラフィック . 225
グラフィック画面 . 68
グラフ ィッ クバレット . 15,24
グラフィック ( G -) RAM …28,163,166,226
クロック . 116
クロックバルス . 179
クロックビット . 179
シーク エラー . 195
シークコマンド . 192
システムクロック . 104
シフト JIS 漢字コード . 65
周波数 . 230
ジョイステイック . 20, 230
シリアル通信 . 114
シリアルマウス . 114
シリンダ ( cylinder ). 180
シリンダ番号 . 201
す
クロマキ ー . 318
"if
ゲームキー . 84
黑色制御 . 26
コマンドレジスタ . 192
コンテイニュアスモード . 156
サーチ . 149,170
最初のセクタ . 208
スーパーインポーズ . 16,35,325
スキューファクタ . 207
スクランブル回路 . 284
スクランブルモード . 284
スクロール IN/OUT . 325
スタートビット . 114,303
スタートポート . 26
ステータス . 189
ステータスレジスタ . 188,206
ステップ•イン/ステップ • アウト…200
ステップレート . 194
ストッブビット . 114,133
スムーススクロール . 35
サイド . 180
サイド番号 . 182
サステイ ー ンレ ー ト . 246
サステイーンレベル . 246
サブ CPU . 17,78
サブレジスタ . 153
し
せ
セクタ (sector). 181,205
セクタ番号 . 204
ゼロカウント . 99
そ
ンーク .
340 試験に出る XI
192
ソフトフォーマット
181,225
ターミナル . 134
タイマ . 99
タイマトリガ . 99
タイマモード . 101
タイマ割り込み . 104
タイムアウト . 99
タイムコンスタント . 99,116
ダウンカウンタ . 100
単密、 . 178
チェックサム エラー . 303
チャンネル . 230
デリーテッドアドレス マーク . 203
転送 . 148,164
Y
トーン . 230
動画面 . 289
時言十 . 92
ドライブのセレクト . 190
トラック . 180
トラックレジスタ . 188,190
日本語文字列の表現方法指定 . 133
つ
通信 . 114
通信制御指定 . 133
通信 パラメータ . 133
. 230
80 C 48. 78
80 C 49. 78
て
データ ビット . 114,133
データ フイールド . 204
テープ . 300
テープのリード/ライト . 303
ディケイレー ト . 246,251
ディスクライト . 199
ディスクリード . 199
ディレクト•リ . 182
テキストアトリビュート . 27
テキストス クロー ル . 166
テキストパレット . 318
テキスト VRAM . 27,161
バーストモード . 155
ハードデイスク . 13
ハーフ トーン回路 . 284
ハイス ピー ドモノクロ . 284
バイトモード . 155,220
倍密 . 178
バス . 148
パスワード . 183
パソコン通信 . 132
パラレルポート . 230
パリティ . 133
ハ•レット設定 . 321
索 引切
フイ-ドノぐンク . 250
フォースインタラブト . 200
フォーマット . 181,208,218
物理フォーマット . 181,223
プライォリティ . 16
ブリスケーラ . 101
ブロック長 . 220
フロ ッ ピー ディ スク . 176,210
プロテクト . 315
"s
ボー ( bps ) . 99
ボーレート . 133,300,310
ボーレー ト ジヱネレー タ . 21
ボインタビット . 154
ボンディングオプション . 114
T
マーワ . 302
マウス . 114
マウスインターフェイス . 98
マウスドライバ . 117
マルチセクタ . 226
マルチタスク . 104,289
マルチブレクス . 220
ミッシングクロック . 208
メイン/バンクメモリ切り換え . 12
も
モーター . 190
モードの指定 . 128
モザイク . 325
T
4096色 . 15,318
ライトトラック . 200,207
ライトレジスタ . 153
ラスタ . 34
T
リーダー . 302
リードトラック . 200, 207
リードレジスタ . 158
リセット . 103
立体ボード . 11
リリースレート . 246,251
れ
レコード番号 . 182,225
レディ信号 . 158
わ
割り込み . 84
割り込みべクトル . 102
342 試験に出る XI
〈著者略歴〉
ISBN 4-930795-88-
落 r 本,乱 r 本はお取り抒えいたしま-
昭和62年12月15【】初版発行
昭和63年6月15 U 第4刷発行
著者 W …平
発行者係正衣
発行所株式会社 H 本 ソフトバンク
出版事業部
T 102東京都千代…区九段南2 -3- 26
003(261)4095
印刷壮光舍印刷株式会社
2F743D81
1412134 D
E 1 3 3 3 9 B
A 0 2 2 2 0 A
3 0 11113
5 F 0 1 0 12
1 F 8 8 B 2 E
3 F 3 3 A 3 3
4 3 0 0 0 0 A
2 2 E E 0 E 2
6FDFF1F1
0FEFF0F2
D99D 3018
4C7C210A
53FC 3127
4BF 22010
4160FF01
2C7EFF00
08080808
00112233
00000000
EEKGEEEE
/ いい、金、
治•谷ソ麼
シ I •、\ / 一 /
V
鱗織
V\/z 〆、、/、'
-、「、_、 ヂ乃咒 つ V
SOFT
BAINIK
ISBN4-930795-88-5 C0055 ¥2800E
定価 2 , 800 円